显然,我完全误解了它的语义。我想到了这样的事情:
http://siteA
-起源。http://siteB
:,我认为这意味着MyCode.js被允许对站点B进行跨域引用。http://siteB
,尽管是跨源请求,但也应该很好。好吧,我错了。它根本不像这样工作。因此,我已经阅读了跨域资源共享,并尝试阅读w3c建议中的跨域资源共享
可以确定的一件事-我仍然不明白我应该如何使用此标头。
我对站点A和站点B都拥有完全控制权。如何使用此标头使从站点A下载的javascript代码能够访问站点B上的资源?
聚苯乙烯
我不想利用JSONP。
Access-Control-Allow-Origin
是CORS(跨源资源共享)标头。
当站点A尝试从站点B获取内容时,站点B可以发送Access-Control-Allow-Origin
响应标头以告知浏览器某些原始来源可以访问此页面的内容。(来源是域,再加上方案和端口号。)默认情况下,其他任何来源都无法访问站点B的页面。使用Access-Control-Allow-Origin
标头会打开一扇门,可以按特定的请求来源进行跨域访问。
对于站点B希望站点A可以访问的每个资源/页面,站点B应在其页面上提供响应标头:
Access-Control-Allow-Origin: http://siteA.com
现代浏览器不会完全阻止跨域请求。如果站点A从站点B请求一个页面,则浏览器实际上将在网络级别上获取请求的页面,并检查响应头是否将站点A列为允许的请求者域。如果网站B未表明允许网站A访问此页面,则浏览器将触发XMLHttpRequest
的error
事件,并拒绝对请求JavaScript代码的响应数据。
什么发生在网络层面可以略微比上述解释更加复杂。如果该请求是“非简单”请求,则浏览器首先发送一个无数据的“预检” OPTIONS请求,以验证服务器将接受该请求。当一个(或两个)同时发生时,请求不是简单的:
Accept
Accept-Language
Content-Language
Content-Type
(当它的值是这仅仅是简单的application/x-www-form-urlencoded
,multipart/form-data
或text/plain
)如果服务器使用与非简单动词和/或非简单头匹配的适当响应头(Access-Control-Allow-Headers
对于非简单头,Access-Control-Allow-Methods
非简单动词)响应OPTIONS预检,则浏览器将发送实际请求。
假设站点A要发送的PUT请求/somePage
,其非简单Content-Type
值为application/json
,则浏览器将首先发送预检请求:
OPTIONS /somePage HTTP/1.1
Origin: http://siteA.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: Content-Type
请注意,Access-Control-Request-Method
和Access-Control-Request-Headers
是由浏览器自动添加的;你无需添加它们。此OPTIONS预检会获取成功的响应标头:
Access-Control-Allow-Origin: http://siteA.com
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: Content-Type
发送实际请求时(完成预检后),其行为与处理简单请求的方式相同。换句话说,将预检成功的非简单请求与简单请求视为相同(即,服务器仍必须Access-Control-Allow-Origin
再次发送以获取实际响应)。
浏览器发送实际请求:
PUT /somePage HTTP/1.1
Origin: http://siteA.com
Content-Type: application/json
{ "myRequestContent": "JSON is so great" }
然后服务器会发送一个Access-Control-Allow-Origin
,就像一个简单的请求一样:
Access-Control-Allow-Origin: http://siteA.com
有关非简单请求的更多信息,请参阅通过CORS理解XMLHttpRequest。
但是,首先,MyCode.js无法访问网站B!此标头将如何到达客户端?顺便说一句,阿凡达》中轻型滑翔机的荣誉。
我进行了明确的编辑:浏览器实际上确实在站点B上执行网络获取以检查
Access-Control-Allow-Origin
标头,但是如果标头不允许站点A拥有它,它可能不会提供对站点A上JS代码的响应。(PS谢谢:))实际上,除非跨域请求得到批准,否则我在Fiddler中看不到任何下载记录。有趣的...
@ Jwan622一个基本的“为什么? ”之类的问题可能不在此特定答案的范围之内,这仅涉及规则和机制。基本上,浏览器允许您,坐在计算机上的人查看来自任何来源的任何资源。它不允许脚本(可由任何人编写)从与运行脚本的页面的来源不同的来源读取资源。一些相关的问题是programmers.stackexchange.com/q/216605,以及相同来源策略的威胁模型是什么?
如果使用身份验证,
Access-Control-Allow-Origin
则*
在某些浏览器(FF和Chrome AFAIK)中不接受。因此,在这种情况下,您必须从Origin
标题中指定值。希望这会对某人有所帮助。