Access-Control-Allow-Origin标头如何工作?

显然,我完全误解了它的语义。我想到了这样的事情:

  1. 客户端从http:// siteA- origin下载javascript代码MyCode.js
  2. MyCode.js的响应标头包含Access-Control-Allow-Origin:http:// siteB,我认为这意味着MyCode.js被允许对站点B进行跨域引用。
  3. 客户端触发了MyCode.js的某些功能,该功能继而向http:// siteB发出了请求,尽管这是跨域请求,但仍然可以。

好吧,我错了。它根本不像这样工作。因此,我已经阅读了跨域资源共享,并尝试阅读w3c建议中的跨域资源共享

可以肯定的是-我仍然不明白我应该如何使用此标头。

我对站点A和站点B都拥有完全控制权。如何使用此标头使从站点A下载的javascript代码能够访问站点B上的资源?

聚苯乙烯

我不想利用JSONP。

Gil小哥伽罗2020/03/09 23:53:12

The Access-Control-Allow-Origin response header indicates whether the response can be shared with requesting code from the given origin.

Header type Response       header
Forbidden header name      no

A response that tells the browser to allow code from any origin to access a resource will include the following:

Access-Control-Allow-Origin: *

For more info, visit here....

Itachi伽罗2020/03/09 23:53:12

Simply paste the following code in your web.config file.

Noted that, you have to paste the following code under <system.webServer> tag

    <httpProtocol>  
    <customHeaders>  
     <add name="Access-Control-Allow-Origin" value="*" />  
     <add name="Access-Control-Allow-Headers" value="Content-Type" />  
     <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />  
    </customHeaders>  
  </httpProtocol>  
前端Eva2020/03/09 23:53:12

If you are using PHP, try adding the following code at the beginning of the php file:

If you are using localhost, try this:

header("Access-Control-Allow-Origin: *");

If you are using external domains such as server, try this:

header("Access-Control-Allow-Origin: http://www.website.com");
Sam阳光2020/03/09 23:53:12

If you want just to test a cross domain application in which the browser blocks your request, then you can just open your browser in unsafe mode and test your application without changing your code and without making your code unsafe. From MAC OS you can do this from the terminal line:

open -a Google\ Chrome --args --disable-web-security --user-data-dir
Tony斯丁2020/03/09 23:53:12

跨域资源共享- CORS(AKA跨域AJAX请求)是大多数Web开发人员可能遇到的问题,根据Same-Origin-Policy,浏览器将客户端JavaScript限制在安全沙箱中,通常JS无法直接与远程服务器通信来自其他域。过去,开发人员创建了许多棘手的方法来实现跨域资源请求,最常用的方法是:

  1. 使用Flash / Silverlight或服务器端作为“代理”与远程通信。
  2. 带有填充的JSON(JSONP)。
  3. 将远程服务器嵌入到iframe中,并通过fragment或window.name进行通信,请参见此处

这些棘手的方式或多或少都存在一些问题,例如,如果开发人员简单地“评估”,JSONP可能会导致安全漏洞;以及上面的#3,尽管它起作用了,但两个域之间应该建立严格的契约,既不灵活也不优雅恕我直言:)

W3C引入了跨域资源共享(CORS)作为标准解决方案,以提供安全,灵活和推荐的标准方式来解决此问题。

机制

从较高的层次上,我们可以简单地认为CORS是域A的客户端AJAX调用与域B上托管的页面之间的合同,典型的跨域请求/响应为:

DomainA AJAX请求标头

Host DomainB.com
User-Agent Mozilla/5.0 (Windows NT 6.1; WOW64; rv:2.0) Gecko/20100101 Firefox/4.0
Accept text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8,application/json
Accept-Language en-us;
Accept-Encoding gzip, deflate
Keep-Alive 115
Origin http://DomainA.com 

DomainB响应标头

Cache-Control private
Content-Type application/json; charset=utf-8
Access-Control-Allow-Origin DomainA.com
Content-Length 87
Proxy-Connection Keep-Alive
Connection Keep-Alive

我在上面标记的蓝色部分是核心事实,“ Origin”请求标头“指示跨域请求或预检请求的来源”,“ Access-Control-Allow-Origin”响应标头指示此页面允许远程请求DomainA(如果值为*,则表示允许来自任何域的远程请求)。

正如我上面提到的,W3建议浏览器在提交实际的跨域HTTP请求之前实现一个“ 预检请求 ”,简而言之,它是一个HTTP OPTIONS请求:

OPTIONS DomainB.com/foo.aspx HTTP/1.1

If foo.aspx supports OPTIONS HTTP verb, it might return response like below:

HTTP/1.1 200 OK
Date: Wed, 01 Mar 2011 15:38:19 GMT
Access-Control-Allow-Origin: http://DomainA.com
Access-Control-Allow-Methods: POST, GET, OPTIONS, HEAD
Access-Control-Allow-Headers: X-Requested-With
Access-Control-Max-Age: 1728000
Connection: Keep-Alive
Content-Type: application/json

Only if the response contains "Access-Control-Allow-Origin" AND its value is "*" or contain the domain who submitted the CORS request, by satisfying this mandtory condition browser will submit the actual Cross-Domain request, and cache the result in "Preflight-Result-Cache".

I blogged about CORS three years ago: AJAX Cross-Origin HTTP request

番长神奇2020/03/09 23:53:12

Access-Control-Allow-OriginCORS(跨源资源共享)标头

当站点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访问此页面,则浏览器将触发XMLHttpRequesterror事件,并拒绝对请求JavaScript代码的响应数据。

非简单请求

什么发生在网络层面可以略微比上述解释更加复杂。如果该请求是“非简单”请求,则浏览器首先发送一个无数据的“预检” OPTIONS请求,以验证服务器将接受该请求。当一个(或两个)同时发生时,请求是不简单的:

  • 使用GET或POST以外的HTTP动词(例如PUT,DELETE)
  • 使用非简单的请求标头;仅有的简单请求标头是:
    • Accept
    • Accept-Language
    • Content-Language
    • Content-Type(当它的值是这仅仅是简单的application/x-www-form-urlencodedmultipart/form-datatext/plain

如果服务器使用与非简单动词和/或非简单头匹配的适当响应头(Access-Control-Allow-Headers对于非简单头,Access-Control-Allow-Methods对于非简单动词)来响应OPTIONS预检,则浏览器将发送实际请求。

Supposing that Site A wants to send a PUT request for /somePage, with a non-simple Content-Type value of application/json, the browser would first send a preflight request:

OPTIONS /somePage HTTP/1.1
Origin: http://siteA.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: Content-Type

Note that Access-Control-Request-Method and Access-Control-Request-Headers are added by the browser automatically; you do not need to add them. This OPTIONS preflight gets the successful response headers:

Access-Control-Allow-Origin: http://siteA.com
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: Content-Type

When sending the actual request (after preflight is done), the behavior is identical to how a simple request is handled. In other words, a non-simple request whose preflight is successful is treated the same as a simple request (i.e., the server must still send Access-Control-Allow-Origin again for the actual response).

The browsers sends the actual request:

PUT /somePage HTTP/1.1
Origin: http://siteA.com
Content-Type: application/json

{ "myRequestContent": "JSON is so great" }

And the server sends back an Access-Control-Allow-Origin, just as it would for a simple request:

Access-Control-Allow-Origin: http://siteA.com

See Understanding XMLHttpRequest over CORS for a little more information about non-simple requests.