Javascript 访问控制请求标头,使用 jQuery 添加到 AJAX 请求的标头中

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10093053/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 23:49:40  来源:igfitidea点击:

Access Control Request Headers, is added to header in AJAX request with jQuery

javascriptjqueryajaxposthttp-headers

提问by fingerup

I would like to add a custom header to an AJAX POST request from jQuery.

我想向来自 jQuery 的 AJAX POST 请求添加自定义标头。

I have tried this:

我试过这个:

$.ajax({
    type: 'POST',
    url: url,
    headers: {
        "My-First-Header":"first value",
        "My-Second-Header":"second value"
    }
    //OR
    //beforeSend: function(xhr) { 
    //  xhr.setRequestHeader("My-First-Header", "first value"); 
    //  xhr.setRequestHeader("My-Second-Header", "second value"); 
    //}
}).done(function(data) { 
    alert(data);
});

When I send this request and I watch with FireBug, I see this header:

当我发送此请求并使用 FireBug 观看时,我看到以下标头:

OPTIONS xxxx/yyyy HTTP/1.1
Host: 127.0.0.1:6666
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:11.0) Gecko/20100101 Firefox/11.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8
Accept-Language: fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Connection: keep-alive
Origin: null
Access-Control-Request-Method: POST
Access-Control-Request-Headers: my-first-header,my-second-header
Pragma: no-cache
Cache-Control: no-cache

选项 xxxx/yyyy HTTP/1.1
Host: 127.0.0.1:6666
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:11.0) Gecko/20100101 Firefox/11.0
Accept: text/html,application/xhtml+ application/xml;q=0.9, /;q=0.8
Accept-Language: fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Connection: keep -alive
来源:null
访问控制请求方法:POST
访问控制请求头:my-first-header,my-second-header
Pragma:no-cache
Cache-Control:no-cache

Why do my custom headers go to Access-Control-Request-Headers:

为什么我的自定义标题转到Access-Control-Request-Headers

Access-Control-Request-Headers: my-first-header,my-second-header

访问控制请求标头:我的第一个标头,我的第二个标头

I was expecting a header values like this:

我期待这样的标题值:

My-First-Header: first value
My-Second-Header: second value

My-First-Header:第一个值
My-Second-Header:第二个值

Is it possible?

是否可以?

采纳答案by karlgold

What you saw in Firefox was not the actual request; note that the HTTP method is OPTIONS, not POST. It was actually the 'pre-flight' request that the browser makes to determine whether a cross-domain AJAX request should be allowed:

您在 Firefox 中看到的不是实际请求;请注意,HTTP 方法是 OPTIONS,而不是 POST。它实际上是浏览器为确定是否应该允许跨域 AJAX 请求而发出的“飞行前”请求:

http://www.w3.org/TR/cors/

http://www.w3.org/TR/cors/

The Access-Control-Request-Headers header in the pre-flight request includes the list of headers in the actual request. The server is then expected to report back whether these headers are supported in this context or not, before the browser submits the actual request.

飞行前请求中的 Access-Control-Request-Headers 标头包括实际请求中的标头列表。然后,在浏览器提交实际请求之前,服务器应报告此上下文中是否支持这些标头。

回答by milkovsky

Here is an example how to set a request header in a jQuery Ajax call:

以下是如何在 jQuery Ajax 调用中设置请求标头的示例:

$.ajax({
  type: "POST",
  beforeSend: function(request) {
    request.setRequestHeader("Authority", authorizationToken);
  },
  url: "entities",
  data: "json=" + escape(JSON.stringify(createRequestObject)),
  processData: false,
  success: function(msg) {
    $("#results").append("The result =" + StringifyPretty(msg));
  }
});

回答by G-raph

This code below works for me. I always use only single quotes, and it works fine. I suggest you should use only single quotes oronly double quotes, but not mixed up.

下面的代码对我有用。我总是只使用单引号,而且效果很好。我建议你应该只使用单引号双引号,但不要混淆。

$.ajax({
    url: 'YourRestEndPoint',
    headers: {
        'Authorization':'Basic xxxxxxxxxxxxx',
        'X-CSRF-TOKEN':'xxxxxxxxxxxxxxxxxxxx',
        'Content-Type':'application/json'
    },
    method: 'POST',
    dataType: 'json',
    data: YourData,
    success: function(data){
      console.log('succes: '+data);
    }
  });

回答by Kamil Kie?czewski

Because you send custom headers so your CORS request is not a simple request, so the browser first sends a preflight OPTIONS request to check that the server allows your request.

因为您发送自定义标头,所以您的 CORS 请求不是简单的请求,所以浏览器首先发送预检 OPTIONS 请求以检查服务器是否允许您的请求。

Enter image description here

在此处输入图片说明

If you turn on CORS on the server then your code will work. You can also use JavaScript fetch instead (here)

如果您在服务器上打开 CORS,那么您的代码将起作用。你也可以使用 JavaScript fetch 代替(这里

let url='https://server.test-cors.org/server?enable=true&status=200&methods=POST&headers=My-First-Header,My-Second-Header';


$.ajax({
    type: 'POST',
    url: url,
    headers: {
        "My-First-Header":"first value",
        "My-Second-Header":"second value"
    }
}).done(function(data) {
    alert(data[0].request.httpMethod + ' was send - open chrome console> network to see it');
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Here is an example configuration which turns on CORS on nginx(nginx.conf file):

这是在 nginx(nginx.conf 文件)打开CORS的示例配置:

location ~ ^/index\.php(/|$) {
   ...
    add_header 'Access-Control-Allow-Origin' "$http_origin" always;
    add_header 'Access-Control-Allow-Credentials' 'true' always;
    if ($request_method = OPTIONS) {
        add_header 'Access-Control-Allow-Origin' "$http_origin"; # DO NOT remove THIS LINES (doubled with outside 'if' above)
        add_header 'Access-Control-Allow-Credentials' 'true';
        add_header 'Access-Control-Max-Age' 1728000; # cache preflight value for 20 days
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'My-First-Header,My-Second-Header,Authorization,Content-Type,Accept,Origin';
        add_header 'Content-Length' 0;
        add_header 'Content-Type' 'text/plain charset=UTF-8';
        return 204;
    }
}

Here is an example configuration which turns on CORS on Apache(.htaccess file)

这是在 Apache 上打开CORS的示例配置(.htaccess 文件)

# ------------------------------------------------------------------------------
# | Cross-domain Ajax requests                                                 |
# ------------------------------------------------------------------------------

# Enable cross-origin Ajax requests.
# http://code.google.com/p/html5security/wiki/CrossOriginRequestSecurity
# http://enable-cors.org/

# <IfModule mod_headers.c>
#    Header set Access-Control-Allow-Origin "*"
# </IfModule>

#Header set Access-Control-Allow-Origin "http://example.com:3000"
#Header always set Access-Control-Allow-Credentials "true"

Header set Access-Control-Allow-Origin "*"
Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS, DELETE, PUT"
Header always set Access-Control-Allow-Headers "My-First-Header,My-Second-Header,Authorization, content-type, csrf-token"

回答by the accountant

And that is why you can't create a bot with JavaScript, because your options are limited to what the browser allows you to do. You can't just order a browser that follows the CORSpolicy, which most browsers follow, to send random requests to other origins and allow you to get the response that simply!

这就是你不能用 JavaScript 创建机器人的原因,因为你的选择仅限于浏览器允许你做的事情。您不能只订购遵循大多数浏览器遵循的 CORS策略的浏览器来向其他来源发送随机请求并允许您简单地获得响应!

Additionally, if you tried to edit some request headers manually, like origin-headerfrom the developers tools that come with the browsers, the browser will refuse your edit and may send a preflight OPTIONSrequest.

此外,如果您尝试手动编辑某些请求标头,例如origin-header使用浏览器附带的开发人员工具,浏览器将拒绝您的编辑并可能发送预检OPTIONS请求。

回答by Jie Sun

Try to use the rack-corsgem. And add the header field in your Ajax call.

尝试使用rack-corsgem。并在您的 Ajax 调用中添加标头字段。