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

客户端从下载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。


当前回答

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

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

其他回答

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

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

访问控制允许源是CORS(跨源资源共享)标头。

当站点A尝试从站点B获取内容时,站点B可以发送一个访问控制允许源站响应标头,告诉浏览器此页面的内容可由特定源站访问。(源站是一个域,加上一个方案和端口号。)默认情况下,站点B的页面不可由任何其他源站访问;使用Access Control Allow Origin(访问控制允许来源)标头为特定请求来源的跨来源访问打开了一扇门。

对于站点B希望站点A访问的每个资源/页面,站点B应为其页面提供响应标题:

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

现代浏览器不会完全阻止跨域请求。如果站点A从站点B请求页面,浏览器将在网络级别实际获取请求的页面,并检查响应标头是否将站点A列为允许的请求者域。如果站点B未指示站点A被允许访问此页面,浏览器将触发XMLHttpRequest的错误事件,并拒绝向请求的JavaScript代码提供响应数据。

非简单请求

在网络层面发生的事情可能比上面解释的稍微复杂一些。如果请求是“非简单”请求,则浏览器首先发送一个无数据的“预检”OPTIONS请求,以验证服务器是否接受该请求。在以下情况之一(或两者)时,请求是非简单的:

使用GET或POST以外的HTTP动词(例如PUT、DELETE)使用非简单请求头;唯一简单的请求头是:接受接受语言内容语言内容类型(仅当其值为application/x-wwww-form-urlencoded、multipart/form-data或text/plain时才简单)

如果服务器使用与非简单谓词和/或非简单标头匹配的适当响应标头(非简单标头的访问控制允许标头,非简单谓词的访问控制方法)响应OPTIONS预检,则浏览器发送实际请求。

假设站点A想要发送一个对/somePage的PUT请求,其中一个非简单的Content-Type值为application/json,浏览器将首先发送一个预检请求:

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

注意,访问控制请求方法和访问控制请求头由浏览器自动添加;您不需要添加它们。此OPTIONS预检获得成功的响应标头:

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

在发送实际请求时(飞行前完成后),行为与处理简单请求的方式相同。换言之,预飞成功的非简单请求被视为简单请求(即,服务器仍然必须再次发送访问控制允许源以获得实际响应)。

浏览器发送实际请求:

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

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

服务器会发回一个“访问控制允许源”,就像对一个简单的请求一样:

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

有关非简单请求的更多信息,请参阅了解CORS上的XMLHttpRequest。

如果您正在使用PHP,请尝试在PHP文件的开头添加以下代码:

如果您使用的是localhost,请尝试以下操作:

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

如果您正在使用外部域(如服务器),请尝试以下操作:

header("Access-Control-Allow-Origin: http://www.website.com");

在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问题,该应用程序必须访问单独的烧瓶服务器。

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

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

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