为啥 CORS AJAX 响应中的响应标头为空?
Posted
技术标签:
【中文标题】为啥 CORS AJAX 响应中的响应标头为空?【英文标题】:Why are response headers null from CORS AJAX response?为什么 CORS AJAX 响应中的响应标头为空? 【发布时间】:2012-09-26 16:01:51 【问题描述】:使用 jsonp 向外部 Play! 发出 AJAX 请求! Heroku上1.2.4应用,返回数据成功,返回null ongetResponseHeaders()
。
这是我的代码:
var ajaxresult;
ajaxresult = $.ajax(
'complete': function (jqXHR, status)
console.log('Complete!');
console.log(status);
console.log("on compelte: " + jqXHR.getAllResponseHeaders());
,
'dataType': "jsonp",
'error': function (jqXHR, status, error)
console.log('Error!');
console.log(status);
console.log(error);
console.log("on error: " + jqXHR.getAllResponseHeaders());
,
'success': function (data, status, jqXHR)
console.log('Success!');
console.log(status);
console.log(data);
console.log("on success: " + ajaxresult.getAllResponseHeaders());
console.log("on success(2): " + jqXHR.getAllResponseHeaders());
,
'type': 'GET',
'url': url + "findAllSpecials"
);
如果我转储 jqXHR 的内容,我会得到:
"readyState: 4","setRequestHeader: function(a,b)if(!s)var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=breturn this","getAllResponseHeaders: function()return s===2?n:null","getResponseHeader: function(a)var c;if(s===2)if(!o)o=;while(c=bG.exec(n))o[c[1].toLowerCase()]=c[2]c=o[a.toLowerCase()]return c===b?null:c","overrideMimeType: function(a)s||(d.mimeType=a);return this","abort: function(a)a=a||\"abort\",p&&p.abort(a),w(0,a);return this","done: function()if(c)var a=c.length;n(arguments),j?l=c.length:e&&e!==!0&&(k=a,o(e[0],e[1]))return this","fail: function()if(c)var a=c.length;n(arguments),j?l=c.length:e&&e!==!0&&(k=a,o(e[0],e[1]))return this","progress: function()if(c)var a=c.length;n(arguments),j?l=c.length:e&&e!==!0&&(k=a,o(e[0],e[1]))return this","state: function()return e","isResolved: function()return!!i","isRejected: function()return!!i","then: function(a,b,c)i.done(a).fail(b).progress(c);return this","always: function()i.done.apply(i,arguments).fail.apply(i,arguments);return this","pipe: function(a,b,c)return f.Deferred(function(d)f.each(done:[a,\"resolve\"],fail:[b,\"reject\"],progress:[c,\"notify\"],function(a,b)var c=b[0],e=b[1],g;f.isFunction(c)?i[a](function()g=c.apply(this,arguments),g&&f.isFunction(g.promise)?g.promise().then(d.resolve,d.reject,d.notify):d[e+\"With\"](this===i?d:this,[g])):i[a](d[e]))).promise()","promise: function(a)if(a==null)a=h;else for(var b in h)a[b]=h[b];return a","success: function()if(c)var a=c.length;n(arguments),j?l=c.length:e&&e!==!0&&(k=a,o(e[0],e[1]))return this","error: function()if(c)var a=c.length;n(arguments),j?l=c.length:e&&e!==!0&&(k=a,o(e[0],e[1]))return this","complete: function()if(c)var a=c.length;n(arguments),j?l=c.length:e&&e!==!0&&(k=a,o(e[0],e[1]))return this","statusCode: function(a)if(a)var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)return this","status: 200","statusText: success"]
在 Opera 和 Firefox 中看到的响应头是:
HTTP/1.1 200 OK
Cache-Control: no-cache
Content-Type: text/plain; charset=utf-8
Server: Play! Framework;1.2.4;prod
Set-Cookie: PLAY_FLASH=;Expires=Fri, 5-Oct-12 12:47:15 GMT;Path=/
Set-Cookie: PLAY_ERRORS=;Expires=Fri, 5-Oct-12 12:47:15 GMT;Path=/
Set-Cookie: PLAY_SESSION=...
Content-Length: 1290
Connection: keep-alive
为什么当浏览器可以看到标题时使用getAllReponseHeaders()
返回null?跨域请求是否会阻止将响应标头发送到 AJAX 响应?
欢迎所有帮助。
谢谢!
【问题讨论】:
【参考方案1】:恐怕大多数浏览器(Mozilla、Safari、Chrome)还不支持Access-Control-Expose-Headers
,所以你的getAllReponseHeaders()
将无法工作..
它在 Mozilla firefox 论坛中作为一个错误提出。但最近他们有一个修复,您可以查看链接This
【讨论】:
【参考方案2】:您的服务器应返回 Access-Control-Expose-Headers
header 以及可读取的标头白名单,如 here 所定义。
我可以在 Firefox 18 和 Chrome 24 中使用此标头。我认为浏览器支持在这里不是问题,至少根据 this site。
确保在 GET(或 POST、PUT、DELETE)的响应中返回此标头,而不仅仅是来自“预检”请求的 OPTIONS 方法。
【讨论】:
这取决于您的服务器语言。如果您使用的是 Java 服务器,则可以编写一个 servlet 过滤器来添加如下所示的标头:response.addHeader("Access-Control-Allow-Headers", "User-Agent, Content-Type, *");
。如果不想自己写过滤器,可以使用this implementation from ebay,直接配置即可。
感谢您发布 andrecardoso。我实际上已经解决了我的问题。你可以看看我在这张票里的评论:***.com/questions/3136140/cors-not-working-on-chrome/…
@andrecardoso:你的意思是Access-Control-Expose-Headers
。 Access-Control-Allow-Headers
仅用于预检请求(经过数小时的调试,我今天痛苦地发现)以上是关于为啥 CORS AJAX 响应中的响应标头为空?的主要内容,如果未能解决你的问题,请参考以下文章
AWS API Gateway 429 响应 - 没有 CORS 标头
AJAX cors 问题:预检响应中的 Access-Control-Allow-Headers 不允许请求标头字段 access-control-allow-credentials
预检请求没问题,然后,经过身份验证,响应不包含允许 cors 标头
为啥没有在 CORS 未命中时设置“Vary: Origin”响应?