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

How does the 'Access-Control-Allow-Origin' header work?

提问人:mark 提问时间:5/17/2012 最后编辑:Peter Mortensenmark 更新时间:11/8/2023 访问量:2498009

问:

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

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

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

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

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

P.S.:我不想使用JSONP

JavaScript 跨域 CORS

评论

7赞 pimvdb 5/17/2012
我不确定,但我相信以这种方式设置标头可以让站点 B 上的代码获取 .http://siteA/MyCode.js
10赞 mark 5/17/2012
但是如何???为了获得标头值,必须首先获取资源,但资源是跨域的,因此浏览器不应该首先阻止请求吗?
1赞 Alex 6/10/2016
您描述的内容实际上类似于另一种做法,即内容安全策略
9赞 Matthew 9/10/2016
@mark 您不必为了获取标头而获取资源。HTTP HEADER 方法将仅返回标头。在 CORS 的情况下,使用 HTTP OPTIONS 方法完成预检,该方法也不会返回正文。Apsillers Answer很好地描述了这一点 stackoverflow.com/posts/10636765/revisions

答:

1868赞 apsillers 5/17/2012 #1

Access-Control-Allow-Origin 是一个 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 访问此页面,则浏览器将触发 的事件,并拒绝向请求的 JavaScript 代码提供响应数据。XMLHttpRequesterror

非简单请求

网络级别上发生的情况可能比上面解释的要复杂一些。如果请求是“非简单”请求,则浏览器首先发送一个无数据的“预检”OPTIONS请求,以验证服务器是否接受该请求。当其中一个(或两个)使用以下命令时,请求是非简单的:

  1. 除 GET 或 POST 以外的 HTTP 动词(例如 PUT、DELETE);
  2. 非简单请求标头;唯一简单的请求标头是:
    • Accept;
    • Accept-Language;
    • Content-Language;
    • Content-Type(仅当其值为 、 或 时,这才简单。application/x-www-form-urlencodedmultipart/form-datatext/plain

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

假设站点 A 想要发送 的 PUT 请求,其非简单值为 ,浏览器将首先发送预检请求:/somePageContent-Typeapplication/json

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

请注意,和是由浏览器自动添加的;您无需添加它们。此 OPTIONS 预检获取成功的响应标头:Access-Control-Request-MethodAccess-Control-Request-Headers

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

评论

4赞 mark 5/17/2012
但是 MyCode.js 首先无法到达站点 B!此标头将如何到达客户端?顺便说一句,为头像中的轻型生活滑翔机点赞。
13赞 apsillers 5/17/2012
我进行了澄清:浏览器实际上确实在站点 B 上执行网络获取以检查标头,但如果标头不允许站点 A 拥有它,它可能不会提供对站点 A 上 JS 代码的响应。(附言谢谢:))Access-Control-Allow-Origin
6赞 Jwan622 7/12/2015
那么,为什么当我在 URL 中键入 HTTP get 请求并检索 JSON 数据时,我的浏览器可以发出 HTTP get 请求,而我的 javascript 客户端却不能呢?
47赞 apsillers 7/13/2015
@Jwan622像这样的基本“为什么?”问题可能超出了这个特定答案的范围,它只是关于规则和机制。基本上,浏览器允许您(坐在计算机前的人)查看来自任何来源的任何资源。它不允许脚本(可以由任何人编写)从与运行脚本的页面的源不同的源读取资源。一些相关问题 programmers.stackexchange.com/q/216605同源策略的威胁模型是什么?
7赞 Zsolti 9/10/2016
在使用身份验证的情况下,在某些浏览器(FF 和 Chrome AFAIK)中不接受。因此,在这种情况下,您必须指定标头中的值。希望这对某人有所帮助。Access-Control-Allow-Origin*Origin
150赞 Wayne Ye 1/23/2014 #2

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

  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

如果 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 请求

评论

0赞 LuqJensen 1/9/2017
这个答案让我意识到为什么我没有将此标头用于 POST 和 GET 请求时突然遇到问题。我不小心直接从磁盘打开了 index.html 文件,因此客户端在 node.js 上访问的 URL 被认为是跨域的,而它只是在本地主机上运行。通过 URL 访问(通常这样做)“解决”了我的问题......
0赞 Dron Bhattacharya 2/25/2022
我有一个公共获取 API。但是有些人告诉启用 CORS,因为它会阻止他们的请求。我知道有一个名为 cors 的 npm 包。但是我看到许多公共 API 没有启用 CORS。我还阅读了一些关于 CORS 安全风险的文章。我问启用 CORS 会不会出错。很少有人从浏览器中运行的客户端代码调用 API。任何建议都非常感谢。
0赞 Timo 9/19/2022
我在你的最后一个链接上读到的:wayneye.com 目前没有任何赞助商给你。
1赞 Wayne Ye 9/20/2022
@Timo我更新了链接: wayneye.me/Ajax-Cross-Origin-HTTP-request 谢谢:)
16赞 OsamaBinLogin 2/27/2016 #3

1. 客户端从 http://siteA 下载 javascript 代码 MyCode.js - 源。

执行下载的代码 - 你的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 进行跨域引用。

不。这意味着,只允许 siteB 执行此请求。因此,您从 siteZ 对 MyCode.js 的请求反而会出错,浏览器通常不会给您任何信息。但是,如果您让服务器返回 A-C-A-O: siteZ,您将获得 MyCode.js 。或者,如果它发送“*”,那将起作用,这将使每个人都进入。或者,如果服务器始终从 Origin: 标头发送字符串...但。。。为了安全起见,如果您害怕黑客,您的服务器应该只允许候选名单上的来源,这些来源被允许发出这些请求。

然后,MyCode.js 来自 siteA。当它向 siteB 发出请求时,它们都是跨域的,浏览器发送 Origin: siteA,siteB 必须获取 siteA,识别它在允许的请求者的短列表中,并发回 A-C-A-O: siteA。只有这样,浏览器才会让您的脚本获取这些请求的结果。

3赞 suryadev 11/28/2016 #4

对于跨域共享,请设置 header:'Access-Control-Allow-Origin':'*';

PHP格式:header('Access-Control-Allow-Origin':'*');

节点:app.use('Access-Control-Allow-Origin':'*');

这将允许共享不同域的内容。

12赞 Melvin Guerrero 1/18/2017 #5

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

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

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

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

header("Access-Control-Allow-Origin: http://www.website.com");
14赞 izik f 2/6/2017 #6

我使用Express.js 4,Node.js 7.4Angular,我遇到了同样的问题。这对我有帮助:

a) 服务器端:在文件 app.js 中,我向所有响应添加标头,例如:

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();
});

这必须在所有路由之前

我看到很多添加的标题:

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”,例如:

$http({
     method: 'POST',
     url: 'url',
     withCredentials: true,
     data : {}
   }).then(function(response){
       // Code
   }, function (response) {
       // Code
});

评论

2赞 The Aelfinn 9/17/2019
res.header('Access-Control-Allow-Origin', req.headers.origin);res.header('Access-Control-Allow-Origin', '*');
0赞 Pipe 8/12/2022
*而且不一样...... 使用凭据时不允许。req.headers.origin*
12赞 Maurizio Brioschi 2/23/2017 #7

如果您只想测试浏览器阻止您的请求的跨域应用程序,那么您可以在不安全模式下打开浏览器并测试您的应用程序,而无需更改您的代码,也不会使您的代码不安全。

macOS 中,您可以从终端行执行此操作:

open -a Google\ Chrome --args --disable-web-security --user-data-dir
94赞 anon 3/5/2017 #8

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

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

在此处输入图像描述

提供的 HTML 页面发出 src 请求。 如今,网络上的许多页面都从不同的域加载了CSS样式表图像脚本等资源(因此它应该很酷)。http://domain-a.com<img>http://domain-b.com/image.jpg

同源策略

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

跨域资源共享 (CORS)

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

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

CORS 的工作原理(Access-Control-Allow-Origin 标头)

维基百科

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

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

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

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

lang-none Origin: http://www.example.com

  1. 服务器可以响应:service.example.com
  • 响应中的 (ACAO) 标头,指示允许哪些源站点。例如:Access-Control-Allow-Origin

    Access-Control-Allow-Origin: http://www.example.com

  • 如果服务器不允许跨域请求,则会出现错误页面

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

    Access-Control-Allow-Origin: *

评论

2赞 Subin Chalil 8/25/2017
如何设置不允许 acees 之类的东西Access-Control-Allow-Origin:null
3赞 Subin Chalil 8/31/2017
当我不想允许任何人通过 CORS 访问我的资源时,我应该设置什么值?我的意思是否定Access-Control-Allow-OriginAccess-Control-Allow-Origin: *
11赞 Peyman Mohamadpour 8/31/2017
只是不要为此目的设置任何东西
1赞 Ganesan J 2/16/2021
我把访问控制放在哪里
1赞 Peyman Mohamadpour 2/16/2021
如果您的 Web 服务器是 Apache,那么您可以放入您的 或 文件http-confightaccess
15赞 Dhaval Jardosh 10/16/2017 #9

使用 ReactAxios,将代理链接加入到 URL 并添加标头,如下所示:

https://cors-anywhere.herokuapp.com/ + Your API URL

只需添加代理链接即可,但它也可能再次引发“无访问”错误。因此,最好添加一个标题,如下所示。

axios.get(`https://cors-anywhere.herokuapp.com/[YOUR_API_URL]`,{headers: {'Access-Control-Allow-Origin': '*'}})
      .then(response => console.log(response:data);
  }

警告:不得在生产中使用

这只是一个快速修复。如果你正在为为什么你无法得到回应而苦苦挣扎,你可以使用它。 但同样,这并不是生产的最佳答案。

评论

31赞 hifromantal 12/9/2017
请不要这样做。使用代理链接就像将用户 cookie 交给中间人。恕我直言,应该是非法的
1赞 C-Note187 1/23/2020
这对我很有用!除了没有使用 *(存在安全问题)之外,我将访问控制限制在我用来学习的确切地址......就我而言,'reqres.in/api/register'
0赞 Rahul Koshti 11/17/2022
就我而言,这是 sampledataapi.com/API/index.php/getcountry
7赞 peachykeen 1/25/2018 #10

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

49赞 Dom 1/29/2018 #11

每当我开始考虑 CORS 时,我对哪个站点托管标头的直觉都是不正确的,就像您在问题中描述的那样。对我来说,思考同源策略的目的会有所帮助。

同源策略的目的是在访问您选择仅与 siteB.com 共享的私人信息 siteA.com 保护您免受恶意 JavaScript 的侵害。如果没有同源策略,siteA.com 的作者编写的 JavaScript 可能会让您的浏览器向 siteB.com 发出请求,使用您的身份验证 Cookie 进行 siteB.com。通过这种方式,siteA.com 可以窃取您与 siteB.com 共享的秘密信息。

有时您需要跨域工作,这就是 CORS 的用武之地。CORS 放宽了 siteB.com 的同源策略,使用标头列出受信任运行可与 siteB.com 交互的 JavaScript 的其他域 (siteA.com)。Access-Control-Allow-Origin

若要了解哪个域应提供 CORS 标头,请考虑以下事项。您访问 malicious.com,其中包含一些尝试向 mybank.com 发出跨域请求的 JavaScript。应该由 mybank.com 而不是 malicious.com 来决定它是否设置放宽同源策略的 CORS 标头,允许来自 malicious.com 的 JavaScript 与之交互。如果 malicous.com 可以设置自己的 CORS 标头,允许自己的 JavaScript 访问 mybank.com,这将完全取消同源策略。

我认为我直觉不佳的原因是我在开发网站时的观点。这是我的网站,还有所有的 JavaScript。因此,它没有做任何恶意的事情,应该由来指定我的 JavaScript 可以与哪些其他站点交互。事实上,我应该考虑:哪些其他网站的 JavaScript 正在尝试与我的网站交互,我应该使用 CORS 来允许它们吗?

评论

2赞 cellepo 4/23/2020
给定第 2 段,您是否在第 3 段中有 siteA、siteB 倒退?我可能是误解了,但前面的段落似乎暗示了它的 siteA 正在运行有问题的 JS?
2赞 Pedro Gabriel Lima 8/11/2020
来自 OP - “我认为我直觉不佳的原因是我在开发网站时的观点。这是我的网站,带有我所有的 JavaScript,因此它没有做任何恶意的事情,应该由我来指定我的 JavaScript 可以与哪些其他网站交互。“ - 对于那些最初这样想的人(就像我一样),还有另一条规则,不是 CORS,为此:CSP(同意安全策略) - 使用 CSP,您可以指定您的网站能够访问/访问的站点/URL。
5赞 Juboraj Sarker 1/20/2019 #12

只需将以下代码粘贴到 web.config 文件中即可。

请注意,您必须将以下代码粘贴到标记下<system.webServer>

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

评论

0赞 Mukesh Salaria 7/30/2021
这对我有帮助。我在WebApiConfig.cs中启用cors,但是我使用了上面的代码并将其放在网络上。配置并删除 WebApiConfig.cs 代码。它像魅力一样工作。谢谢
0赞 Peter Mortensen 9/18/2022
什么系统?IIS/ASP.NETweb.config 文件
1赞 Alireza 1/31/2019 #13

Access-Control-Allow-Origin 响应标头指示 响应可以与从给定源请求代码共享。

Header type                 Response header
-------------------------------------------
Forbidden header name       no

告诉浏览器允许来自任何源的代码的响应 访问资源将包括以下内容:

Access-Control-Allow-Origin: *

有关更多信息,请访问 Access-Control-Allow-Origin...

评论

0赞 Peter Mortensen 9/18/2022
相关新闻: 答案完全复制,但归属正确
22赞 Ben 11/19/2019 #14

根据我自己的经验,很难找到一个简单的解释,为什么CORS甚至是一个问题。

一旦你明白了它为什么在那里,标题和讨论就会变得更加清晰。我会用几行来试一试。


这一切都与cookie有关。Cookie 按其域存储在客户端上。

一个示例故事:在您的计算机上,有一个 cookie 。也许你的会话就在那里。yourbank.com

眼:当客户端向服务器发出请求时,它将为该请求发送存储在域下的 cookie。

您已在浏览器上登录到 。您请求查看您的所有帐户,并发送 cookie 以用于 。 接收一堆 cookie 并发回其响应(您的帐户)。yourbank.comyourbank.comyourbank.com

如果另一个客户端向服务器发出跨域请求,则会像以前一样发送这些 cookie。呸。

浏览到 。恶意向不同的银行发出一堆请求,包括 .malicious.comyourbank.com

由于 cookie 按预期进行验证,因此服务器将授权响应。

这些 cookie 被收集起来并发送 - 现在,有来自 .malicious.comyourbank

哎呀。


所以现在,一些问题和答案变得显而易见:

  • “我们为什么不直接阻止浏览器这样做呢?”是的。这就是CORS。

  • “我们该如何绕过它?”让服务器告诉请求 CORS 正常。

评论

0赞 Cameron 10/14/2021
我喜欢这个答案,我觉得这是对的,但我不明白为什么似乎只有前端抛出错误,而后端可能仍然处理请求。我写了一个关于它的问题 stackoverflow.com/questions/69559952/......
2赞 Ben 10/14/2021
后端只能看到一个来自一个 URL 的请求。的后端(明确地)不知道它正在发出请求。浏览器是唯一可以跟踪您访问过的所有不同域的地方yourbank.commalicious.com
0赞 Niton 10/25/2022
确实允许请求通过,但发送的 cookie 始终来自请求域,这不是更有意义吗?
0赞 Ben 10/26/2022
@Niton你完全理解它,他们就是这样。问题是可以向...然后收集并发送 cookie。然后,响应返回到 。malicious.comyourbank.comyourbank.commalicious.com
2赞 Kamil Kiełczewski 5/15/2020 #15

Nginx 和 Apache

作为对apsiller答案的补充,我想添加一个wiki图表,该图表显示请求何时简单或不简单(以及OPTIONS预检请求是否发送)

Enter image description here

对于一个简单的请求(例如,热链接图像),你不需要更改你的服务器配置文件,但你可以在应用程序中添加标头(托管在服务器上,例如,在PHP中),就像Melvin Guerrero在他的回答中提到的那样 - 但请记住:如果你在服务器(配置)中添加完整的CORS标头,同时允许在应用程序中使用简单的CORS(例如, PHP),这根本行不通。

以下是两个常用服务器的配置:

  • 在 Nginx 上打开 CORSnginx.conf 文件)

    location ~ ^/index\.php(/|$) {
       ...
        add_header 'Access-Control-Allow-Origin' "$http_origin" always; # if you change "$http_origin" to "*" you shoud get same result - allow all domain to CORS (but better change it to your particular domain)
        add_header 'Access-Control-Allow-Credentials' 'true' always;
        if ($request_method = OPTIONS) {
            add_header 'Access-Control-Allow-Origin' "$http_origin"; # DO NOT remove THIS LINES (doubled with outside 'if' above)
            add_header 'Access-Control-Allow-Credentials' 'true';
            add_header 'Access-Control-Max-Age' 1728000; # cache preflight value for 20 days
            add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';  # arbitrary methods
            add_header 'Access-Control-Allow-Headers' 'My-First-Header,My-Second-Header,Authorization,Content-Type,Accept,Origin'; # arbitrary headers
            add_header 'Content-Length' 0;
            add_header 'Content-Type' 'text/plain charset=UTF-8';
            return 204;
        }
    }

  • 在 Apache 上打开 CORS.htaccess 文件)

    # ------------------------------------------------------------------------------
    # | Cross-domain Ajax requests                                                 |
    # ------------------------------------------------------------------------------
    
    # Enable cross-origin Ajax requests.
    # http://code.google.com/p/html5security/wiki/CrossOriginRequestSecurity
    # http://enable-cors.org/
    
    # change * (allow any domain) below to your domain
    Header set Access-Control-Allow-Origin "*"
    Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS, DELETE, PUT"
    Header always set Access-Control-Allow-Headers "My-First-Header,My-Second-Header,Authorization, content-type, csrf-token"
    Header always set Access-Control-Allow-Credentials "true"

0赞 Cyclion 6/18/2020 #16

注意:只是测试的临时解决方案

对于那些无法控制后端的人,这是Chrome浏览器的解决方法。Options 405 Method Not Allowed

在命令行中执行:

"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --disable-web-security --user-data-dir="path_to_profile"

例:

"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --disable-web-security --user-data-dir="C:\Users\vital\AppData\Local\Google\Chrome\User Data\Profile 2"

评论

2赞 Tushar Shukla 12/23/2020
还请提及这样做的严重风险,包括安全性和可能的数据泄露。另外,请注意,这绝不是推荐的解决方案,而只是为了在开发过程中测试某些东西,而且非常谨慎。
1赞 Vince 3/9/2021
你永远不应该这样做,这是对安全性的破坏,这永远不会帮助其他人了解如何使用 CORS。不惜一切代价避免这种情况 PLZ
5赞 Ehsan Ali 3/10/2021 #17

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

对于 Firefox:

CORS 无处不在

对于 Google Chrome:

允许 CORS:Access-Control-Allow-Origin

注意:CORS适用于以下配置:

Allow CORS options

CORS Everywhere options

0赞 rohit.khurmi095 10/26/2021 #18

对于使用 Angular 的 .NET Core 3.1 API

启动.cs:添加CORS

    //SERVICES
    public void ConfigureServices(IServiceCollection services){

        //CORS (Cross Origin Resource Sharing)
        //=====================================
        services.AddCors();
    }

    //MIDDLEWARES
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        app.UseRouting();

        //ORDER: CORS -> Authentication -> Authorization)
        //CORS (Cross Origin Resource Sharing)
        //=====================================  
        app.UseCors(x=>x.AllowAnyHeader().AllowAnyMethod().WithOrigins("http://localhost:4200"));

        app.UseHttpsRedirection();
    }
}

控制器:为授权控制器启用 CORS

 //Authorize all methods inside this controller
 [Authorize]
 [EnableCors()]
 public class UsersController : ControllerBase
 {
    //ActionMethods
 }
-3赞 Matteus Barbosa 2/8/2023 #19

这很奇怪,但可能会发生 CORS 问题,因为您正在尝试通过客户端 ajax 从作为前端基本库的 react、angular、jquery 应用程序请求。

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

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

我尝试了来自前端的请求,但没有奏效,然后我使用 curl 发出了相同的请求,并且成功了。

评论

1赞 j.karlsson 3/20/2023
我不明白你的意思。Web 服务器如何知道请求是来自前端还是后端?这都只是另一个 HTTP 请求。