当前位置: 首页 > 知识库问答 >
问题:

“Access-Control-Allow-Origin”标头是如何工作的?

羊冠玉
2023-03-14

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

  1. 客户端从超文本传输协议下载JavaScript代码MyCode.js://siteA-原点。
  2. MyCode.js的响应头包含Access-Control-Allow-Origin:超文本传输协议://siteB,我认为这意味着MyCode.js被允许对站点B进行跨域引用。
  3. 客户端触发MyCode.js的一些功能,这些功能又向超文本传输协议://siteB发出请求,尽管是跨域请求,这应该没问题。

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

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

我拥有站点A和站点B的完全控制权。我如何使用这个头让从站点A下载的JavaScript代码访问站点B上的资源?

附言:我不想使用JSONP。

共有3个答案

邹开畅
2023-03-14

根据Mozilla开发者网络的这篇文章,

当资源从不同于第一个资源本身服务的域或端口请求资源时,它会发出跨源HTTP请求。

提供的HTML页面http://domain-a.com生成

出于安全原因,浏览器限制从脚本中发起的跨域HTTP请求。例如,XMLHttpRequestFetch遵循主域同源策略。因此,使用XMLHttpRequestFetch的Web应用程序只能向其自己的域发出HTTP请求。

为了改进 Web 应用程序,开发人员要求浏览器供应商允许跨域请求。

跨域资源共享(CORS)机制为Web服务器提供跨域访问控制,从而实现安全的跨域数据传输。现代浏览器在API容器中使用CORS——例如XMLHttpRequestFetch——来降低跨域HTTP请求的风险。

维基百科:

CORS标准描述了新的HTTP标头,这些标头为浏览器和服务器提供了一种仅在具有权限时才请求远程URL的方法。

尽管服务器可以执行一些验证和授权,但通常浏览器有责任支持这些标头并遵守它们施加的限制。

  1. 浏览器发送带有Origin HTTP标头的OPTIONS请求。

此标头的值是为父页面提供服务的域。当来自的页面http://www.example.com尝试访问service.example中的用户数据。com,以下请求头将发送到service.example.com:

Origin: http://www.example.com

> < li>

响应中的< code > Access-Control-Allow-Origin (ACAO)标头,指示允许哪些原始站点。例如:

访问控制-允许-源:http://www.example.com

如果服务器不允许跨源请求,则显示错误页

带有通配符的Access Control Allow Origin(ACAO)头,允许所有域:

< code >访问控制允许来源:*

欧阳睿范
2023-03-14

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

  1. 使用闪存/银光或服务器端作为“代理”与遥控器通信。
  2. JSON 带填充 (JSONP).
  3. 将远程服务器嵌入到 iframe 中,并通过片段或 window.name 进行通信,请参阅此处。

这些棘手的方法或多或少都有一些问题,例如JSONP可能会导致安全漏洞,如果开发人员只是“eval”它,以及上面的#3,虽然它有效,但两个域都应该在彼此之间建立严格的契约,它既不灵活也不优雅。

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

机制

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

域名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

我上面标记的蓝色部分是kernal事实,“Origin”请求标头“指示跨源请求或预检请求的来源”,“访问控制允许源”响应标头指示此页面允许来自 DomainA 的远程请求(如果值为 * 表示允许来自任何域的远程请求)。

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

OPTIONS DomainB.com/foo.aspx HTTP/1.1

如果 foo.aspx支持选项 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

仅当响应包含“访问控制-允许-源”并且其值为“*”或包含提交 CORS 请求的域时,通过满足此强制条件,浏览器才会提交实际的跨域请求,并将结果缓存在“预检结果缓存”中。

三年前,我写了一篇关于CORS的博客:AJAX跨源HTTP请求

钱均
2023-03-14

访问控制允许源是 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访问该页面,浏览器将触发< code>XMLHttpRequest的< code>error事件,并拒绝请求JavaScript代码的响应数据。

网络层发生的事情可能比上面解释的稍微复杂一些。如果请求是“非简单”请求,浏览器首先发送无数据的“预检”选项请求,以验证服务器是否会接受该请求。在下列情况下,请求不简单:

  • 使用GET或POST以外的HTTP动词(例如PUT、DELETE)
  • 使用非简单请求标头;唯一简单的请求标头是:
  • 接受
  • 接受-语言
  • 内容-语言
  • Content-Type(仅当其值为application/x-wan-form-urlencodedmultipart/form-datatext/平原时才简单)

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

假设站点 A 想要发送 /somePage 的 PUT 请求,其非简单内容类型值为应用程序/json,浏览器将首先发送一个预检请求:

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

请注意,浏览器会自动添加访问控制请求方法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。

 类似资料:
  • 问题内容: 显然,我完全误解了它的语义。我想到了这样的事情: 客户端从http:// siteA- origin 下载javascript代码MyCode.js 。 MyCode.js的响应标头包含 Access-Control-Allow-Origin:http:// siteB ,我认为这意味着MyCode.js被允许对站点B进行跨域引用。 客户端触发了MyCode.js的某些功能,该功能继而

  • Response.AddHeader(“Access-Control-Allow-Origin”,“*”)是如何实现的;行设置多个标题时,包括,但没有当我删除它?

  • 我从ASP.NET表单中调用这个函数,在调用Ajax时在firebug控制台中得到以下错误。 跨源请求被阻止:同一源策略不允许读取http://anotherdomain/test.json上的远程资源。(原因:CORS标头“Access-Control-Allow-Origin”丢失)。 我做了其他的方法,但仍然找不到解决办法。 注意:我没有服务器权限进行服务器端(API/URL)更改。

  • Access-Control-Allow-Origin响应 header 指示是否该响应可以与具有给定资源共享原点。 Header type Response header Forbidden header name no 语法 Access-Control-Allow-Origin: *Access-Control-Allow-Origin: <origin> 指令 * 对于没有凭据的请求,服务

  • 问题内容: 将web.xml移植到Java配置后出现以下问题 根据一些Spring参考,尝试了以下尝试: 所选择的值来自有效的web.xml过滤器: 有什么想法为什么Spring java config方法不能像web.xml文件那样工作? 问题答案: 将CorsMapping从更改方法。 为整个应用程序启用CORS很简单: 你可以轻松更改任何属性,以及仅将此CORS配置应用于特定的路径模式: 控

  • 我很难强制S3在它从一个bucket返回的所有对象上设置CORS头,尽管启用了CORS,但由于客户端S3上传正在工作,返回的对象没有CORS头! 我启用的策略是: 对象URL示例https://s3.amazonaws.com/captionable/meme/test 有人知道怎么了吗?