即使源完全匹配,Access-Control-Allow-Origin也拒绝XmlHttpRequest

时间:2012-11-26 21:23:04

标签: javascript http cors

生命体征:

Chrome版本23.0.1271.64 Mac OS X 10.8.2

情况:

我在https://api.myapi.com/公开了一个网络服务... 我想允许JavaScript应用程序与此API进行交互。 CORS感觉明显最合适(jsonp和朋友是可怕的,可怕的黑客)。

我可以在我的开发人员工具中看到正在发送预检请求:

Request URL: https://api.myapi.com/someapi
Request Method: OPTIONS
Status Code: 200 OK

Request Headers

Accept: */*
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Access-Control-Request-Headers: origin, authorization, accept
Access-Control-Request-Method: GET
Connection: keep-alive
Host: api.myapi.com
Origin: http://prototypes.mycompany.com
Referer: http://prototypes.mycompany.com/somepage.html
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11

Response Headers

Access-Control-Allow-Headers: Accept,Authorization,Content-Length,Content-Type,Cookie
Access-Control-Allow-Methods: GET,POST,PUT,DELETE,HEAD,OPTIONS
Access-Control-Allow-Origin: http://prototypes.mycompany.com
Access-Control-Allow-Credentials: true
Connection: close

这看起来很棒,特别是响应Access-Control-Allow-Origin标题似乎与请求Origin标题完全匹配。

之后,立即尝试实际请求:

Request URL: https://api.myapi.com/someapi

Request Headers

Accept: application/json, text/javascript, */*; q=0.01
Authorization: <custom authentication scheme, removed>
Origin: http://prototypes.mycompany.com
Referer: http://prototypes.mycompany.com/somepage.html
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11

然后显示为“已取消”并发出以下错误:

  

XMLHttpRequest无法加载https://api.myapi.com/someapi。 Access-Control-Allow-Origin不允许原点http://prototypes.mycompany.com

我最初以*作为我允许的来源开始,但是在完全相同的问题上失败了。

我已经在iOS 5的Mobile Safari和Firefox上复制了这个问题。在Firefox中,行为更令人困惑: 服务器响应200 OK,然后响应6-7KB的数据(这是我所期望的)。客户端日志说它有200个OK和~300个字节的数据(没有响应头,根本没有响应......)然后触发“错误”处理程序。

我错过了什么?

2 个答案:

答案 0 :(得分:1)

问题解决了!我不得不突破gdb来解决这个问题......

代理服务器正在将自己的CORS标头插入请求中。因此,HTTP会话具有多次指定的标头。安全检查正在检查第一个标头,即&#34; *&#34;,并且请求失败。请求失败打印出 last 标头值,看起来是正确的。

不是很有帮助,WebKit!

答案 1 :(得分:0)

想法:

  • 我注意到您的Origin中没有Access-Control-Allow-Headers。我不认为他们是必要的,但你有Content-Length我不认为这也是必要的。

  • 您正在使用Authorization,您认为应该使用credentials吗? (显然有时你应该在回复中加入Access-Control-Allow-Credentials: true。)

(这些几乎不值得“回答”,但愚蠢的评论不允许换行。)