Access-Control-Allow-Origin头部不起作用 - 我做错了什么?

19

我试图使用一个Access-Control-Allow-Origin头来响应HTTP OPTIONS方法,并将请求中的Origin头的内容复制到该头中。

显然,这并没有起作用,原因我无法确定。

tl;dr: OPTIONS方法的响应显示:

Access-Control-Allow-Origin: http://10.0.0.105:9294

后续的GET请求具有:

Origin:http://10.0.0.105:9294

Chrome说:

Origin http://10.0.0.105:9294 is not allowed by Access-Control-Allow-Origin

这是什么意思?

更多细节...

通过查看Chrome的开发者工具窗口,请求头如下:

OPTIONS /user/kris HTTP/1.1
Host: 10.0.0.104:8080
Connection: keep-alive
Access-Control-Request-Method: GET
Origin: http://10.0.0.105:9294
User-Agent: Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.75 Safari/537.1
Access-Control-Request-Headers: origin, x-requested-with, content-type, accept
Accept: */*
Referer: http://10.0.0.105:9294/
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-GB,en-US;q=0.8,en;q=0.6
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3

响应头如下:

HTTP/1.0 200 OK
Date: Mon, 13 Aug 2012 11:23:45 GMT
Server: WSGIServer/0.1 Python/2.7.3
Content-Length: 0
Access-Control-Allow-Methods: GET, PUT, POST, DELETE, HEAD, OPTIONS
Access-Control-Max-Age: 10
Access-Control-Allow-Origin: http://10.0.0.105:9294
Access-Control-Allow-Headers: X-Requested-With, Authorization, X-Huzu-User, Content-Type, Accept
Content-Type: text/html; charset=UTF-8

在 jQuery 发送 OPTIONS 请求并获得上述响应后,会发生两件奇怪的事情。 OPTIONS 响应(即 200)会显示为错误。

OPTIONS http://10.0.0.104:8080/user/kris 200 (OK)

此后GET请求被拒绝。控制台中显示错误:

XMLHttpRequest cannot load http://10.0.0.104:8080/user/kris. Origin http://10.0.0.105:9294 is not allowed by Access-Control-Allow-Origin.
我看不出为什么不行。我做错了什么吗?

我没有一个最小的jQuery代码失败示例可以在这里发布,因为它对解决问题没有任何用处。假设javascript代码没有任何奇怪之处,即它只是一个单一的jQuery get(),导致上面发布的OPTIONS请求。我的问题是:响应出了什么问题? - scav
是我一个人感觉还是主机URL(10.0.0.104:8080)和引用URL(10.0.0.105:9294/)之间有差异? - rene
@rene:10.0.0.104:8080不是请求的来源,它是服务器本身。Javascript是从10.0.0.105:9294加载的,因此那才是来源。或者我完全误解了吗?将尝试使用10.0.0.105上的浏览器,看看是否有所帮助。顺便说一句,我认为某些浏览器(如FF)只接受该标头中的单个主机。 - scav
在同一主机上运行浏览器和JavaScript应用程序是没有帮助的。 - scav
这可能与http://stackoverflow.com/questions/11580200/cors-request-isnt-allowed-despite-headers-being-set相同。 - scav
显示剩余2条评论
1个回答

33

好的,我明白了。似乎需要适当处理预检请求 (OPTIONS) 是跨站点资源请求能够工作的必要条件,但不足以让其起作用。

在 OPTIONS 请求返回满意的标头后,随后针对同一 URL 的任何后续请求的所有响应也必须具有必要的 "Access-Control-Allow-Origin" 标头,否则浏览器将会吞掉它们,并且它们甚至不会显示在调试器窗口中。

因此,它看起来像是因为 OPTIONS 响应中的某些问题而取消了请求,但实际上,浏览器正在查看真实请求的响应头,然后拒绝它们。


既然你已经完成了你的查询,能否帮我解决这个类似的问题?http://stackoverflow.com/questions/11953132/no-response-obtained-while-implementing-cors - Prashant Singh
@scav +1 真心感谢你,这省了我好几小时的调试时间! - alf
1
如果实际响应中设置的Access-Control-Allow-Origin:*与预检OPTIONS请求中使用的不完全匹配,则也会失败。我在asp dot net中意外地将其添加了两次,一次在IIS配置中,一次在页面加载代码中,这意味着Access-Control-Allow-Origin:*在预检OPTIONS中出现了一次,但在实际响应中出现了两次,因此Chrome取消了它。 - Martin Belcher - AtWrk
3
仅仅是为了支持这一点... Chrome(目前v33)似乎要求304响应也必须具有“Access-Control-Allow-Origin:*”等标头,而不仅仅是在初始选项响应上。 Firefox(v27)似乎并不介意。 - Anentropic
非常有效 - 我有一个文件请求另一个文件,设置两个文件的头部解决了问题 :) - Rog
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接