使用jQuery在AJAX请求中添加标头

时间:2012-04-10 16:56:41

标签: javascript jquery ajax post http-headers

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

我试过这个:

$.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);
});

当我发送此请求并使用FireBug观看时,我会看到此标题:

  

选项xxxx / yyyy HTTP / 1.1
      主持人:127.0.0.1:6666
      User-Agent:Mozilla / 5.0(Windows NT 6.1; WOW64; rv:11.0)Gecko / 20100101 Firefox / 11.0
      接受: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
      连接:保持活力
      来源:null
      访问控制请求方法:POST
      访问控制请求标头:my-first-header,my-second-header
      Pragma:no-cache
      缓存控制:无缓存

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

  

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

我期待这样的标头值:

  

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

有可能吗?

8 个答案:

答案 0 :(得分:397)

以下是如何在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));
  }
});

答案 1 :(得分:138)

以下代码适用于我。我总是只使用单引号,它工作正常。我建议你应该只使用单引号或仅使用双引号,但不要混淆。

$.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);
    }
  });

希望这能回答你的问题...

答案 2 :(得分:121)

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

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

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

答案 3 :(得分:1)

这就是为什么您无法使用Javascript创建机器人,因为您的选项仅限于浏览器允许您执行的操作。您不能只按照大多数浏览器遵循的CORS政策订购浏览器,将随机请求发送到其他来源,并让您简单地获得响应!

此外,如果您尝试从浏览器附带的开发人员工具手动编辑某些请求标头(如origin-header),浏览器将拒绝您的修改,并可能会发送预检OPTIONS请求。 / p>

答案 4 :(得分:0)

因为您发送了自定义标头,所以CORS请求为NOT SIMPLE REQUEST,所以浏览器首先发送了prefilight OPTIONS请求,以检查服务器是否允许您的请求。

enter image description here

如果您在服务器上打开CORS,则您的代码将可用。您也可以改用js fetch(here

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>

以下是示例配置,该配置在nginx上打开 CORS (nginx.conf文件)

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;
    }
}

以下是示例配置,该配置在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"

答案 5 :(得分:0)

从客户端来看,我无法解决此问题。 从nodejs express方面,您可以使用cors模块进行处理。

var express       = require('express');
var app           = express();
var bodyParser = require('body-parser');
var cors = require('cors');

var port = 3000; 
var ip = '127.0.0.1';

app.use('*/myapi', 
          cors(), // with this row OPTIONS has handled
          bodyParser.text({type:'text/*'}),
          function( req, res, next ){
    console.log( '\n.----------------' + req.method + '------------------------' );
        console.log( '| prot:'+req.protocol );
        console.log( '| host:'+req.get('host') );
        console.log( '| url:'+req.originalUrl );
        console.log( '| body:',req.body );
        //console.log( '| req:',req );
    console.log( '.----------------' + req.method + '------------------------' );
    next();
    });

app.listen(port, ip, function() {
    console.log('Listening to port:  ' + port );
});
 
console.log(('dir:'+__dirname ));
console.log('The server is up and running at http://'+ip+':'+port+'/');

没有cors(),此选项已在POST之前显示。

.----------------OPTIONS------------------------
| prot:http
| host:localhost:3000
| url:/myapi
| body: {}
.----------------OPTIONS------------------------

.----------------POST------------------------
| prot:http
| host:localhost:3000
| url:/myapi
| body: <SOAP-ENV:Envelope .. P-ENV:Envelope>
.----------------POST------------------------

ajax调用:

$.ajax({
    type: 'POST',
    contentType: "text/xml; charset=utf-8",
// these does not works
    //beforeSend: function(request) { 
    //  request.setRequestHeader('Content-Type', 'text/xml; charset=utf-8');
    //  request.setRequestHeader('Accept', 'application/vnd.realtime247.sct-giro-v1+cms');
    //  request.setRequestHeader('Access-Control-Allow-Origin', '*');
    //  request.setRequestHeader('Access-Control-Allow-Methods', 'POST, GET');
    //  request.setRequestHeader('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type');
    //},
    //headers: {
    //  'Content-Type': 'text/xml; charset=utf-8',
    //  'Accept': 'application/vnd.realtime247.sct-giro-v1+cms',
    //  'Access-Control-Allow-Origin': '*',
    //  'Access-Control-Allow-Methods': 'POST, GET',
    //  'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type'
    //},
    url: 'http://localhost:3000/myapi',             
    data:       '<SOAP-ENV:Envelope .. P-ENV:Envelope>',                
    success: function( data ) {
      console.log(data.documentElement.innerHTML);
    },
    error: function(jqXHR, textStatus, err) {
      console.log( jqXHR,'\n', textStatus,'\n', err )
    }
  });

答案 6 :(得分:0)

尝试添加添加'Content-Type':'application/json'

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

答案 7 :(得分:-10)

尝试使用rack-cors gem。并在ajax调用中添加标题字段。