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

客户端从下载JavaScript代码MyCode.jshttp://siteA-原产地。MyCode.js的响应标头包含Access Control Allow Origin:http://siteB,我认为这意味着允许MyCode.js对站点B进行跨源引用。客户端触发MyCode.js的一些功能,进而向http://siteB,这应该可以,尽管是跨源请求。

嗯,我错了。它根本不是这样工作的。所以,我已经阅读了跨源资源共享,并尝试阅读w3c推荐中的跨源资源分享。

有一点是肯定的——我仍然不明白我应该如何使用这个标题。

我完全控制站点A和站点B。如何使从站点A下载的JavaScript代码使用此标头访问站点B上的资源?

备注:我不想使用JSONP。


当前回答

大多数CORS问题是因为您试图通过客户端ajax从前端基本库react、angular、jquery应用程序请求。

您必须从后端应用程序请求。

您正在尝试从前端API请求,但您尝试使用的API期望此请求来自后端应用程序,并且它永远不会接受客户端请求。

其他回答

我无法在后端服务器上配置它,但通过浏览器中的这些扩展,它对我很有用:

对于Firefox:

CORS无处不在

对于Google Chrome:

允许CORS:访问控制允许源

注意:CORS适用于此配置:

1.客户端从http://siteA-原产地。

进行下载的代码-您的html脚本标记或来自javascript的xhr或其他任何东西-来自,比方说,http://siteZ.而且,当浏览器请求MyCode.js时,它会发送一个Origin:头,上面写着“Origin:http://siteZ“,因为它可以看到您正在请求siteA和siteZ!=siteA。(您不能停止或干扰此操作。)

2.MyCode.js的响应头包含Access Control Allow Origin:http://siteB,我认为这意味着允许MyCode.js对站点B进行跨源引用。

不。这意味着,只有站点B才允许执行此请求。因此,您从siteZ请求MyCode.js时会出现错误,浏览器通常不会提供任何信息。但是如果你让你的服务器返回A-C-A-O:siteZ,你会得到MyCode.js。或者如果它发送'*',这会起作用,这会让所有人都进来。或者如果服务器总是从Origin:header发送字符串。。。但是为了安全起见,如果你害怕黑客,你的服务器应该只允许短名单上的来源,允许他们提出这些请求。

然后,MyCode.js来自siteA。当它向站点B发出请求时,它们都是跨源的,浏览器发送origin:siteA,站点B必须接收站点A,识别它在允许的请求者的短列表中,然后发送A-C-A-O:siteA。只有这样,浏览器才会让脚本获得这些请求的结果。

跨源资源共享-CORS(A.K.A.跨域AJAX请求)是大多数web开发人员可能遇到的问题,根据同源策略,浏览器在安全沙盒中限制客户端JavaScript,通常JS无法直接与来自不同域的远程服务器通信。过去,开发人员创建了许多复杂的方法来实现跨域资源请求,最常用的方法是:

使用Flash/SSilverlight或服务器端作为“代理”进行通信使用遥控器。带填充的JSON(JSONP)。在iframe中嵌入远程服务器,并通过fragment或window.name进行通信,请参阅此处。

这些棘手的方法或多或少都有一些问题,例如,如果开发人员简单地“评估”JSONP,JSONP可能会导致安全漏洞,而上面的第3条,虽然它有效,但两个域之间应该建立严格的契约,它既不灵活也不优雅IMHO:)

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

如果foo.aspx支持OPTIONS HTTP动词,它可能会返回如下响应:

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

只有当响应包含“Access Control Allow Origin”且其值为“*”或包含提交CORS请求的域时,通过满足此强制条件,浏览器才会提交实际的跨域请求,并将结果缓存在“Preflight result cache”中。

三年前,我在博客中写到了CORS:AJAX跨源HTTP请求

Access Control Allow Origin响应标头指示响应可以与来自给定源的请求代码共享。标头类型响应标头-------------------------------------------禁止的标题名称编号告诉浏览器允许任何来源的代码访问资源将包括以下内容:访问控制允许来源:*

有关详细信息,请访问访问控制允许来源。。。

在Python中,我一直在成功地使用Flask CORS库。它使处理CORS变得非常容易和轻松。我从下面的库文档中添加了一些代码。

安装:

pip install -U flask-cors

允许所有路由上所有域的CORS的简单示例:

from flask import Flask
from flask_cors import CORS

app = Flask(__name__)
CORS(app)

@app.route("/")
def helloWorld():
  return "Hello, cross-origin-world!"

有关更多具体示例,请参阅文档。我使用了上面的简单示例来解决我正在构建的Ionic应用程序中的CORS问题,该应用程序必须访问单独的烧瓶服务器。