How does Access-Control-Allow-Origin header work?
显然,我完全误解了它的语义。我想到了这样的事情:
嗯,我错了。它根本不能这样工作。因此,我阅读了跨源资源共享,并尝试阅读W3C推荐中的跨源资源共享。
有一件事是肯定的-我仍然不明白我应该如何使用这个标题。
我对站点A和站点B都有完全的控制权。如何使从站点A下载的javascript代码能够使用这个头部访问站点B上的资源?
附笔。
我不想使用JSONP。
当读取的内容从网站到网站tries B B网站的CAN发送响应到一
为每个网站的页面资源的访问是想让B到B网站,网站页面的响应应该是它的标题:
1 | Access-Control-Allow-Origin: http://siteA.com |
现代浏览器的跨域请求将不完全阻滞。如果网站的页面请求从浏览器的网站B,将实际的页面读取请求在网络级和检查,如果响应标头中的requester域允许的网站。如果网站没有得到证明,B是允许访问的网站浏览到这个网页,将触发的事件和
非简单的请求。
什么是发生在网络层,可以解释更多的比上述的复杂点。如果请求的是一个"非简单的浏览器发送的请求,"第一"预检过程无日期"选项的请求到服务器,验证,将接受的请求。当请求是一个非方(或双方):
- 使用HTTP GET或POST(动词比其他例如PUT、DELETE)
- 使用非简单的请求标头的头;唯一的要求是:简单
Accept Accept-Language Content-Language Content-Type (这仅仅是一个简单的时候,它的价值是application/x-www-form-urlencoded ,multipart/form-data ,或text/plain )
如果服务器响应的选项报头(
这是supposing网站想把请求发
1 2 3 4 | OPTIONS /somePage HTTP/1.1 Origin: http://siteA.com Access-Control-Request-Method: PUT Access-Control-Request-Headers: Content-Type |
请注意,是由
1 2 3 | Access-Control-Allow-Origin: http://siteA.com Access-Control-Allow-Methods: GET, POST, PUT Access-Control-Allow-Headers: Content-Type |
当发送请求后,目前是做预检过程)是相同的,该行为是如何简单的请求处理。在其他的话,非简单的请求是成功的,是其预检过程的简单处理的请求(即,服务器必须发送一
在当前的浏览器发送的请求。
1 2 3 4 5 | PUT /somePage HTTP/1.1 Origin: http://siteA.com Content-Type: application/json {"myRequestContent":"JSON is so great" } |
和服务器发送一
1 | Access-Control-Allow-Origin: http://siteA.com |
基于CORS的XMLHttpRequest的ESS的理解更多一点的信息是关于非简单的要求。
跨源请求共享-
这些棘手的方法或多或少有一些问题,例如,如果开发人员简单地"评估"它,以及上面的3,JSONP可能会导致安全漏洞,尽管它有效,但两个域之间应该建立严格的合同,既不灵活也不优雅imho:。
W3C引入了跨源资源共享(cors)作为标准解决方案,以提供安全、灵活和推荐的标准方法来解决这个问题。
机制
从高层来看,我们可以简单地认为CORS是来自域A的客户机Ajax调用和托管在域B上的页面之间的契约,典型的跨源请求/响应是:
域Ajax请求头
1 2 3 4 5 6 7 | 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 |
域B响应头
1 2 3 4 5 6 | 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 |
上面标记的蓝色部分是核心事实,"来源"请求头"表示跨来源请求或飞行前请求的来源","访问控制允许来源"响应头表示此页允许来自域A的远程请求(如果值为*表示允许来自任何域的远程请求)。
如上所述,W3建议浏览器在提交实际的跨源HTTP请求之前实现一个"飞行前请求",简而言之,它是一个HTTP
1 | OPTIONS DomainB.com/foo.aspx HTTP/1.1 |
如果foo.aspx支持选项http动词,它可能返回如下响应:
1 2 3 4 5 6 7 8 | 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 |
只有当响应包含"访问控制允许源站"且其值为"*"或包含提交CORS请求的域时,浏览器才会通过满足此命令条件提交实际的跨域请求,并将结果缓存到"飞行前结果缓存"中。
三年前我写了一篇关于CORS的博客:Ajax跨源HTTP请求
这个问题有点太老了,无法回答,但我会把它贴出来,以备将来参考。
根据这篇Mozilla开发者网络文章,
A resource makes a cross-origin HTTP request when it requests a resource from a different domain, or port than the one which the first resource itself serves.
从
出于安全原因,浏览器限制从脚本内启动的跨源HTTP请求。例如,
为了改进Web应用程序,开发人员要求浏览器供应商允许跨域请求。
跨源资源共享(CORS)机制为Web服务器提供跨域访问控制,从而实现安全的跨域数据传输。现代浏览器在API容器(如
维基百科:
The CORS standard describes new HTTP headers which provide browsers and servers a way to request remote URLs only when they have permission.
Although some validation and authorization can be performed by the server, it is generally the browser's responsibility to support these headers and honor the restrictions they impose.
例子
浏览器发送带有
此头的值是为父页提供服务的域。当来自
来源:http://www.example.com
响应中的
Access-Control-Allow-Origin 头(acao),指示允许哪些源站。例如:Access-Control-Allow-Origin: http://www.example.com 如果服务器不允许跨源请求,则为错误页。
带通配符的
Access-Control-Allow-Origin 头(acao),允许所有域:Access-Control-Allow-Origin: *
每当我开始考虑CORS时,我对于哪个站点承载头部的直觉是错误的,正如您在问题中描述的那样。对我来说,这有助于思考同一原产地政策的目的。
相同来源策略的目的是保护您不受Sitea.com上恶意javascript的攻击,因为您选择只与Siteb.com共享私人信息。如果没有相同的源站策略,由sitea.com作者编写的javascript可以使您的浏览器使用siteb.com的身份验证cookie向siteb.com发出请求。这样,sitea.com就可以窃取您与siteb.com共享的机密信息。
有时候你需要跨领域工作,这就是CORS的切入点。CORS为domaina.com放宽了相同的源站策略,使用
要了解哪个域应该为CORS头提供服务,请考虑这一点。您访问恶意网站,其中包含一些试图向mybank.com发出跨域请求的javascript。应该由mybank.com而不是恶意网站来决定是否设置CORS头文件来放宽同一源文件策略,从而允许恶意网站的javascript与之交互。如果malicous.com可以设置自己的cors头文件,允许自己的javascript访问mybank.com,这将完全取消相同的源代码策略。
我认为我直觉不好的原因是我在开发一个站点时的观点。它是我的站点,有我所有的javascript,因此它没有做任何恶意的事情,应该由我来指定我的javascript可以与哪些其他站点交互。实际上,我应该考虑哪些其他的网站javascript正试图与我的网站交互,我应该使用CORS来允许它们?
如果您只想测试浏览器阻止您请求的跨域应用程序,那么您可以在不安全模式下打开浏览器并测试应用程序,而不更改代码,也不使代码不安全。从Mac OS,您可以从终端线路执行此操作:
1 | open -a Google\ Chrome --args --disable-web-security --user-data-dir |
使用react和axios,将代理链接连接到URL并添加头,如下所示
只需添加代理链接就可以了,但它也会抛出错误,导致无法再次访问。因此最好添加标题,如下所示。
1 2 3 | axios.get(`https://cors-anywhere.herokuapp.com/[YOUR_API_URL]`,{headers: {'Access-Control-Allow-Origin': '*'}}) .then(response => console.log(response:data); } |
我在Express 4和Node 7.4以及Angular上工作,我遇到了同样的问题我可以帮助解决这个问题:
a)服务器端:在文件app.js中,我向所有响应提供头文件,如:
1 2 3 4 5 | app.use(function(req, res, next) { res.header('Access-Control-Allow-Origin', req.headers.origin); res.header("Access-Control-Allow-Headers","Origin, X-Requested-With, Content-Type, Accept"); next(); }); |
这必须在所有路由器之前完成。
我看到很多添加了这个标题:
1 2 3 | res.header("Access-Control-Allow-Headers","*"); res.header('Access-Control-Allow-Credentials', true); res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE'); |
但我不需要那个,
b)客户端:在发送Ajax中,需要添加:"withcredentials:true",比如:
1 2 3 4 5 6 7 8 9 10 | $http({ method: 'POST', url: 'url, withCredentials: true, data : {} }).then(function(response){ // code }, function (response) { // code }); |
祝你好运。
1。客户机从http://sitea-the origin下载javascript代码mycode.js。
下载的代码——你的HTML脚本标签或者JavaScript的XHR或者其他什么——来自http://sitez。当浏览器请求mycode.js时,它会发送一个origin:header,上面写着"origin:http://sitez",因为它可以看到您请求的是sitea和sitez!= SITEA。(您不能停止或干扰此操作。)
2。mycode.js的响应头包含access control allow origin:http://site b,我认为这意味着mycode.js可以跨源引用站点b。
不。这意味着,只有SiteB可以执行此请求。因此,您从Sitez请求mycode.js会得到一个错误,而浏览器通常不会给您任何信息。但是,如果让服务器返回a-c-a-o:sitez,则会得到mycode.js。或者,如果它发送"*",就可以了,这样就可以让所有人都进来了。或者如果服务器总是从源服务器发送字符串:header…但是…为了安全起见,如果您害怕黑客,您的服务器应该只允许来自一个短名单的来源,这是允许作出这些请求的。
然后,mycode.js来自Sitea。当它向SiteB发出请求时,它们都是跨源的,浏览器发送origin:SiteA,SiteB必须获取SiteA,识别出它在允许请求者的短列表中,然后发送回a-c-a-o:SiteA。只有这样,浏览器才会让脚本得到这些请求的结果。
在python中,我已经成功地使用了
安装:
1 | $ pip install -U flask-cors |
允许所有路由上所有域的CORS的简单示例:
1 2 3 4 5 6 7 8 9 | from flask import Flask from flask_cors import CORS app = Flask(__name__) CORS(app) @app.route("/") def helloWorld(): return"Hello, cross-origin-world!" |
有关更具体的示例,请参阅文档。我使用了上面的简单例子来解决CORS问题,在我构建的一个离子应用程序中,它必须访问一个单独的烧瓶服务器。
如果您使用的是PHP,请尝试在PHP文件的beaning处添加以下代码:
如果您使用的是localhost,请尝试以下操作:
1 | header("Access-Control-Allow-Origin: *"); |
如果您使用的是服务器等外部域,请尝试以下操作:
1 | header("Access-Control-Allow-Origin: http://www.website.com"); |
对于跨源共享,设置header:
php:
节点:
这将允许共享不同域的内容。
只需将以下代码粘贴到web.config文件中。
注意,您必须将以下代码粘贴到
1 2 3 4 5 6 7 | <httpProtocol> <customHeaders> </customHeaders> </httpProtocol> |
The Access-Control-Allow-Origin response header indicates whether the
response can be shared with requesting code from the given origin.
1 2 | 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:
1 | Access-Control-Allow-Origin: * |
更多信息,请访问此处….