xmlhttprequest不能加载xxx no' access-control-allow-oligin'标题
tl; dr;关于相同的原始策略,
我有一个grunt过程,该过程启动了express.js服务器的实例。到目前为止,当它开始提供一个空白页面,以下内容出现在开发人员的Chrome(最新版本)中:
xmlhttprequest不能加载 https://www.example.com/ 在请求的 资源。 Origin' http:// localhost:4300 '因此不允许访问。
是什么阻止我访问页面?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(11)
tl; dr -   当您想使用客户端JS读取数据时(主要)从其他服务器中读取数据时,您需要带有数据的服务器来授予想要数据的代码的明确许可。
最终有一个摘要,答案的标题使得更容易找到相关部分。不过,推荐阅读所有内容,因为它为理解为什么提供了有用的背景,从而使如何更轻松地在不同情况下使用。
关于相同的来源策略,
这是
您的特殊情况正在显示如何为XMLHTTPRequest实施(如果您使用Fetch,您将获得相同的结果),但它也适用于其他事物(例如,将图像加载到
< canvas> 或加载到
< iframe>
中的文档,仅具有略有不同的实现。可以用三个字符
https://www.example.com/
在您的示例中)http:// http:// localhost:4300
in您的示例)爱丽丝已登录到鲍勃的网站,并在那里有一些机密数据。也许这是一家公司Intranet(仅适用于LAN上的浏览器)或她的在线银行业务(仅在输入用户名和密码后获得的cookie访问)。
爱丽丝(Alice)访问了马洛里(Mallory)的网站,该网站上有一些JavaScript,该网站使爱丽丝(Alice)的浏览器向鲍勃(Bob)的网站提出了HTTP请求(从她的IP地址带有cookie等)。这可能就像使用
XMLHTTPREQUEST
并读取ResponseText
一样简单。浏览器的相同起源策略可防止JavaScript阅读Bob网站返回的数据(Bob和Alice不希望Mallory访问该数据)。 (请注意,例如,您可以使用ORININS跨越
< img>
元素显示图像,因为图像的内容不会暴露于JavaScript(或Mallory)…,除非您将Canvas扔到在这种情况下,您将 产生相同的原始违规错误)。为什么当您认为不适合
任何给定的URL时适用相同的来源策略,因此不需要SOP。这种情况是几个常见的情况:
……但是浏览器无法知道上述任何一种是正确的,因此信任不是自动的,并且应用了SOP。在浏览器将其从BOB收到的数据提供给其他网站之前,必须明确授予许可。
为什么相同的原点策略适用于网页中的JavaScript,而
网页
浏览器扩展
*
之外的其他几乎没有其他内容,浏览器开发人员工具中的“网络”选项卡,以及诸如Postman之类的应用程序已安装软件。他们没有将数据从一个网站传递到属于另一个网站的JavaScript,只是因为您访问了该网站。安装软件通常需要更有意识的选择。没有被认为是风险的第三方(马洛里)。
*
浏览器扩展名确实需要仔细编写,以避免交叉原始问题。 <大多数时候在网页内部
,仅在网页上显示某些内容时,没有大量信息泄漏。
如果您使用
&lt; img&gt;
元素加载图像,则将显示在页面上,但很少有信息暴露于Mallory。 JavaScript无法读取图像(除非您使用Crossorigin
属性明确启用了使用CORS的请求许可),然后将其复制到她的服务器。That said, some information does leak so, to quote Domenic Denicola (of Google):
这就是为什么您需要CORS许可才能跨越来源的字体。
为什么您可以在页面上显示数据而不使用JS阅读数据,
在许多情况下,Mallory的网站可能会导致浏览器从第三方获取数据并显示(例如,添加
&lt; img&gt; 元素显示图像)。 Mallory的JavaScript不可能在该资源中读取数据,只有Alice的浏览器和Bob的服务器才能做到这一点,因此仍然是安全的。
CORS
access-control-allow-Origin
http 响应错误消息中引用的标题是 cors 标准,允许鲍勃可以明确授予Mallory的网站,以通过Alice的浏览器访问数据。基本的实现将包括:
…在响应标题中允许任何网站读取数据。
…仅允许一个特定的站点访问它,Bob可以根据
Origin
request 标题动态生成该站点,以允许多个(但不是全部)访问它的网站。BOB设置该响应标头的细节取决于Bob的HTTP服务器和/或服务器端编程语言。 node.js/express.js的用户应使用已记录良好的cors middleware 。其他平台的用户应查看此用于各种常见配置的指南可能会有所帮助。
NB:有些请求很复杂,并发送a preflight 选项请求服务器必须在浏览器发送get/post/put/JS想要提出的任何请求之前必须响应。仅将
访问控制
添加到特定URL中的CORS的实现通常会被此地绊倒。显然,通过CORS授予许可才是Bob只有只有在这两个时才做的:
我如何添加这些标题?
这取决于您的服务器端环境。
如果可以的话,请使用旨在处理COR的库,因为它们会为您提供简单的选项,而不必手动处理所有内容。
enable-cors.org 列出了有关特定平台和框架的文档列表,您可能会发现有用。
但是我不是鲍勃!
mallory 没有添加此标头的标准机制,因为它必须来自鲍勃的网站,她无法控制。
如果Bob正在运行公共API,则可能会有一种机制可以打开CORS(也许是以某种方式格式化请求,或在登录Bob网站的开发人员门户网站后的配置选项)。不过,这必须是鲍勃实施的一种机制。马洛里(Mallory)可以在鲍勃(Bob)的网站上阅读文档,以查看是否有东西,或者她可以与鲍勃(Bob)交谈并要求他实施CORS。
错误消息提及“前飞行的响应”
某些交叉原始请求是。
当(粗略地说)您尝试提出一个交叉原始请求时,该请求:
Enctype 或其他一些请求标头)。
如果您正确地执行了需要前飞行前的某些事情
,则其余部分仍然适用,但您还需要确保服务器可以收听前线请求(这将是
选项
(而不是get
,post
,或您要发送的任何内容),并使用正确的access-control-allow响应它-origin
标题,但访问控制
访问权限>访问controll-allow-headers ,如果您 允许您的特定HTTP方法或标题在尝试构建AJAX请求时,有时会出错
,有时会犯错误,有时这些触发了前飞行的需求。 会触发
的常见错误
content-type放置:application/json
在没有请求主体的内容的get请求上(通常是在作者混淆content> content-type
时)和接受
)。在这两种情况下,删除额外的请求标头通常足以避免进行前飞行的需要(这将在与支持简单请求但不前闪烁请求的API交流时解决问题)。
不透明的响应(
no-Cors
模式)有时您需要提出HTTP请求,但是您无需阅读响应。例如,如果您将日志消息发布到服务器以进行录制。
如果您正在使用 /a>(而不是
xmlhttprequest
),然后您可以将其配置为不使用CORS。请注意,这不会让您做任何需要Cors做的事情。 您将无法阅读响应。您将无法提出需要前飞行的请求。
它将让您提出一个简单的请求,看不到响应,而不会填充开发人员控制台中的错误消息。
当您使用
fetch
提出请求时,给出的Chrome错误消息解释了如何做,并且没有获得使用CORS查看响应的权限:因此:
CORS
JSONP
BOB的替代方案还可以使用hack提供数据,例如 jsonp 是人们在CORS出现之前进行交叉原始Ajax的方式。
它通过以JavaScript程序的形式呈现数据,该数据将数据注入Mallory的页面。
它要求Mallory Trust Bob不要提供恶意代码。
注意共同的主题:提供数据的网站必须告诉浏览器,第三方网站可以访问它发送给浏览器的数据是可以的。
由于JSONP通过附加
&lt; script&gt;
元素加载数据以javascript程序的形式加载数据,该javaScript程序在页面中调用函数,试图在返回JSON的URL上使用JSONP技术会失败 - 通常会出现CORB错误 - 因为JSON不是JavaScript。则将两个资源移至单个原点
如果JS运行的HTML文档,并且所请求的URL在相同的原点上(共享相同的方案,主机名和端口), ,然后将相同的Origin Policy Policy Grants授予许可。不需要CORS。
代理
Mallory 可以使用服务器端代码获取数据(然后像往常一样,她可以通过HTTP从服务器传递到Alice的浏览器)。
它将要么:
与可以编写服务器端代码的 &amp;由第三方(例如任何地方的CORS)主持。请注意,这一点的隐私含义:第三方可以监视谁代理他们的服务器。
鲍勃不需要授予任何权限。
这里没有安全感,因为这仅在马洛里和鲍勃之间。鲍勃没有办法认为马洛里是爱丽丝,并为马洛里提供了应该在爱丽丝和鲍勃之间保密的数据。
因此,马洛里只能使用此技术来读取 public 数据。
但是,请注意,从别人的网站上获取内容并自己展示它可能违反了版权并为您开放法律行动。
编写除Web应用以外的其他内容
,如“为什么相同的原始策略仅适用于网页中的JavaScript”部分,您可以通过不在网页中编写JavaScript来避免SOP。
这并不意味着您不能继续使用JavaScript和HTML,但是您可以使用其他一些机制(例如Node-Webkit或PhoneGap)进行分发。
浏览器扩展程序
可能在应用相同的原点策略之前,浏览器扩展名将CORS标头注入响应中。
这些对于开发可能很有用,但对于生产站点不实用(要求您网站的每个用户安装禁用其浏览器安全功能的浏览器扩展程序是不合理的)。
它们还倾向于仅处理简单的请求(处理前跨选项请求时失败)。
具有适当的开发环境,并具有本地开发服务器
通常是一种更好的方法。
其他安全风险
请注意,SOP/CORS不会减轻 XSS :://en.wikipedia.org/wiki/cross-site_request_forgery“ rel =“ noreferrer”> csrf 或 SQL注入需要独立处理的攻击。
总而言之,
tl;dr — When you want to read data, (mostly) using client-side JS, from a different server you need the server with the data to grant explicit permission to the code that wants the data.
There's a summary at the end and headings in the answer to make it easier to find the relevant parts. Reading everything is recommended though as it provides useful background for understanding the why that makes seeing how the how applies in different circumstances easier.
About the Same Origin Policy
This is the Same Origin Policy. It is a security feature implemented by browsers.
Your particular case is showing how it is implemented for XMLHttpRequest (and you'll get identical results if you were to use fetch), but it also applies to other things (such as images loaded onto a
<canvas>
or documents loaded into an<iframe>
), just with slightly different implementations.The standard scenario that demonstrates the need for the SOP can be demonstrated with three characters:
https://www.example.com/
in your example)http://localhost:4300
in your example)Alice is logged into Bob's site and has some confidential data there. Perhaps it is a company intranet (accessible only to browsers on the LAN), or her online banking (accessible only with a cookie you get after entering a username and password).
Alice visits Mallory's website which has some JavaScript that causes Alice's browser to make an HTTP request to Bob's website (from her IP address with her cookies, etc). This could be as simple as using
XMLHttpRequest
and reading theresponseText
.The browser's Same Origin Policy prevents that JavaScript from reading the data returned by Bob's website (which Bob and Alice don't want Mallory to access). (Note that you can, for example, display an image using an
<img>
element across origins because the content of the image is not exposed to JavaScript (or Mallory) … unless you throw canvas into the mix in which case you will generate a same-origin violation error).Why the Same Origin Policy applies when you don't think it should
For any given URL it is possible that the SOP is not needed. A couple of common scenarios where this is the case are:
… but the browser has no way of knowing if either of the above is true, so trust is not automatic and the SOP is applied. Permission has to be granted explicitly before the browser will give the data it has received from Bob to some other website.
Why the Same Origin Policy applies to JavaScript in a web page but little else
Outside the web page
Browser extensions
*
, the Network tab in browser developer tools, and applications like Postman are installed software. They aren't passing data from one website to the JavaScript belonging to a different website just because you visited that different website. Installing software usually takes a more conscious choice.There isn't a third party (Mallory) who is considered a risk.
*
Browser extensions do need to be written carefully to avoid cross-origin issues. See the Chrome documentation for example.Inside the webpage
Most of the time, there isn't a great deal of information leakage when just showing something on a webpage.
If you use an
<img>
element to load an image, then it gets shown on the page, but very little information is exposed to Mallory. JavaScript can't read the image (unless you use acrossOrigin
attribute to explicitly enable request permission with CORS) and then copy it to her server.That said, some information does leak so, to quote Domenic Denicola (of Google):
This is why you need CORS permission to load fonts across origins.
Why you can display data on the page without reading it with JS
There are a number of circumstances where Mallory's site can cause a browser to fetch data from a third party and display it (e.g. by adding an
<img>
element to display an image). It isn't possible for Mallory's JavaScript to read the data in that resource though, only Alice's browser and Bob's server can do that, so it is still secure.CORS
The
Access-Control-Allow-Origin
HTTP response header referred to in the error message is part of the CORS standard which allows Bob to explicitly grant permission to Mallory's site to access the data via Alice's browser.A basic implementation would just include:
… in the response headers to permit any website to read the data.
… would allow only a specific site to access it, and Bob can dynamically generate that based on the
Origin
request header to permit multiple, but not all, sites to access it.The specifics of how Bob sets that response header depend on Bob's HTTP server and/or server-side programming language. Users of Node.js/Express.js should use the well-documented CORS middleware. Users of other platforms should take a look at this collection of guides for various common configurations that might help.
NB: Some requests are complex and send a preflight OPTIONS request that the server will have to respond to before the browser will send the GET/POST/PUT/Whatever request that the JS wants to make. Implementations of CORS that only add
Access-Control-Allow-Origin
to specific URLs often get tripped up by this.Obviously granting permission via CORS is something Bob would only do only if either:
How do I add these headers?
It depends on your server-side environment.
If you can, use a library designed to handle CORS as they will present you with simple options instead of having to deal with everything manually.
Enable-Cors.org has a list of documentation for specific platforms and frameworks that you might find useful.
But I'm not Bob!
There is no standard mechanism for Mallory to add this header because it has to come from Bob's website, which she does not control.
If Bob is running a public API then there might be a mechanism to turn on CORS (perhaps by formatting the request in a certain way, or a config option after logging into a Developer Portal site for Bob's site). This will have to be a mechanism implemented by Bob though. Mallory could read the documentation on Bob's site to see if something is available, or she could talk to Bob and ask him to implement CORS.
Error messages which mention "Response for preflight"
Some cross-origin requests are preflighted.
This happens when (roughly speaking) you try to make a cross-origin request that:
enctype
or some other request header(s)).If you are correctly doing something that needs a preflight
In these cases then the rest of this answer still applies but you also need to make sure that the server can listen for the preflight request (which will be
OPTIONS
(and notGET
,POST
, or whatever you were trying to send) and respond to it with the rightAccess-Control-Allow-Origin
header but alsoAccess-Control-Allow-Methods
andAccess-Control-Allow-Headers
to allow your specific HTTP methods or headers.If you are triggering a preflight by mistake
Sometimes people make mistakes when trying to construct Ajax requests, and sometimes these trigger the need for a preflight. If the API is designed to allow cross-origin requests but doesn't require anything that would need a preflight, then this can break access.
Common mistakes that trigger this include:
Access-Control-Allow-Origin
and other CORS response headers on the request. These don't belong on the request, don't do anything helpful (what would be the point of a permissions system where you could grant yourself permission?), and must appear only on the response.Content-Type: application/json
header on a GET request that has no request body the content of which to describe (typically when the author confusesContent-Type
andAccept
).In either of these cases, removing the extra request header will often be enough to avoid the need for a preflight (which will solve the problem when communicating with APIs that support simple requests but not preflighted requests).
Opaque responses (
no-cors
mode)Sometimes you need to make an HTTP request, but you don't need to read the response. e.g. if you are posting a log message to the server for recording.
If you are using the
fetch
API (rather thanXMLHttpRequest
), then you can configure it to not try to use CORS.Note that this won't let you do anything that you require CORS to do. You will not be able to read the response. You will not be able to make a request that requires a preflight.
It will let you make a simple request, not see the response, and not fill the Developer Console with error messages.
How to do it is explained by the Chrome error message given when you make a request using
fetch
and don't get permission to view the response with CORS:Thus:
Alternatives to CORS
JSONP
Bob could also provide the data using a hack like JSONP which is how people did cross-origin Ajax before CORS came along.
It works by presenting the data in the form of a JavaScript program that injects the data into Mallory's page.
It requires that Mallory trust Bob not to provide malicious code.
Note the common theme: The site providing the data has to tell the browser that it is OK for a third-party site to access the data it is sending to the browser.
Since JSONP works by appending a
<script>
element to load the data in the form of a JavaScript program that calls a function already in the page, attempting to use the JSONP technique on a URL that returns JSON will fail — typically with a CORB error — because JSON is not JavaScript.Move the two resources to a single Origin
If the HTML document the JS runs in and the URL being requested are on the same origin (sharing the same scheme, hostname, and port) then the Same Origin Policy grants permission by default. CORS is not needed.
A Proxy
Mallory could use server-side code to fetch the data (which she could then pass from her server to Alice's browser through HTTP as usual).
It will either:
That server-side code could be written & hosted by a third party (such as CORS Anywhere). Note the privacy implications of this: The third party can monitor who proxies what across their servers.
Bob wouldn't need to grant any permissions for that to happen.
There are no security implications here since that is just between Mallory and Bob. There is no way for Bob to think that Mallory is Alice and to provide Mallory with data that should be kept confidential between Alice and Bob.
Consequently, Mallory can only use this technique to read public data.
Do note, however, that taking content from someone else's website and displaying it on your own might be a violation of copyright and open you up to legal action.
Writing something other than a web app
As noted in the section "Why the Same Origin Policy only applies to JavaScript in a web page", you can avoid the SOP by not writing JavaScript in a webpage.
That doesn't mean you can't continue to use JavaScript and HTML, but you could distribute it using some other mechanism, such as Node-WebKit or PhoneGap.
Browser extensions
It is possible for a browser extension to inject the CORS headers in the response before the Same Origin Policy is applied.
These can be useful for development but are not practical for a production site (asking every user of your site to install a browser extension that disables a security feature of their browser is unreasonable).
They also tend to work only with simple requests (failing when handling preflight OPTIONS requests).
Having a proper development environment with a local development server
is usually a better approach.
Other security risks
Note that SOP / CORS do not mitigate XSS, CSRF, or SQL Injection attacks which need to be handled independently.
Summary
目标服务器必须允许交叉原始请求。为了通过Express允许它,只需处理HTTP选项请求:
Target server must allowed cross-origin request. In order to allow it through express, simply handle http options request :
因为在接受的答案中没有提到这一点。
您可以使用简单请求。
为了执行“简单请求”,请求需要满足几个条件。例如只允许
POST
、GET
和HEAD
方法,以及只允许某些给定的 headers(您可以找到所有条件 此处)。如果您的客户端代码没有在请求中使用固定值显式设置受影响的标头(例如“接受”),则可能会出现某些客户端使用某些“非标准”值自动设置这些标头的情况,从而导致服务器不接受它作为简单请求 - 这会给你一个 CORS 错误。
As this isn't mentioned in the accepted answer.
You can make use of Simple Requests.
In order to perform a 'Simple Requests' the request needs to meet several conditions. E.g. only allowing
POST
,GET
andHEAD
method, as well as only allowing some given Headers (you can find all conditions here).If your client code does not explicit set affected Headers (e.g. "Accept") with a fix value in the request it might occur that some clients do set these Headers automatically with some "non-standard" values causing the server to not accept it as Simple Request - which will give you a CORS error.
这是由于 CORS 错误而发生的。 CORS 代表跨源资源共享。简而言之,当我们尝试从另一个域访问一个域/资源时,就会发生此错误。
在这里阅读更多相关信息:jquery 的 CORS 错误
要解决此问题,如果您有权访问其他域,您必须在服务器中允许 Access-Control-Allow-Origin。这可以添加到标题中。您可以为所有请求/域或特定域启用此功能。
如何获取跨域资源共享(CORS)发布请求工作
这些链接可能会有所帮助
This is happening because of the CORS error. CORS stands for Cross Origin Resource Sharing. In simple words, this error occurs when we try to access a domain/resource from another domain.
Read More about it here: CORS error with jquery
To fix this, if you have access to the other domain, you will have to allow Access-Control-Allow-Origin in the server. This can be added in the headers. You can enable this for all the requests/domains or a specific domain.
How to get a cross-origin resource sharing (CORS) post request working
These links may help
此CORS问题没有进一步阐述(其他原因)。
我目前正在出现此问题。
我的前端还返回“访问控制”标头错误。
只是我指出了错误的URL,因此该标头无法正确反射(我认为它确实如此)。 Local主机(前端) - &GT;致电非安全HTTP(应该是HTTPS),请确保前端的API端点指向正确的协议。
This CORS issue wasn't further elaborated (for other causes).
I'm having this issue currently under different reason.
My front end is returning 'Access-Control-Allow-Origin' header error as well.
Just that I've pointed the wrong URL so this header wasn't reflected properly (in which i kept presume it did). localhost (front end) -> call to non secured http (supposed to be https), make sure the API end point from front end is pointing to the correct protocol.
我在Chrome控制台中遇到了同样的错误。
我的问题是,我试图使用
http://
而不是https://
来访问网站。因此,没有什么可解决的,只需使用https
才能进入同一站点。I got the same error in Chrome console.
My problem was, I was trying to go to the site using
http://
instead ofhttps://
. So there was nothing to fix, just had to go to the same site usinghttps
.这个错误花了我2天。我检查了我的服务器日志,浏览器chrome/edge和服务器之间的跨越前选项请求/响应还可以。主要原因是xhtmlrequest的get/post/put/delete 服务器响应还必须具有以下标题:
“ onect”在请求标题中(浏览器将添加它要求您)。例如:
您可以将响应标头添加到以下内容中以接受:
或特定请求的响应标头,例如:
浏览器中的消息尚不清楚:“ ...“ ...请求的资源”
请注意:
CORS在Localhost中效果很好。不同的端口意味着不同的域。
如果收到错误消息,请检查服务器端的CORS配置。
This bug cost me 2 days. I checked my Server log, the Preflight Option request/response between browser Chrome/Edge and Server was ok. The main reason is that GET/POST/PUT/DELETE server response for XHTMLRequest must also have the following header:
"origin" is in the request header (Browser will add it to request for you). for example:
you can add response header like the following to accept for all:
or response header for a specific request like:
The message in browsers is not clear to understand: "...The requested resource"
note that:
CORS works well for localhost. different port means different Domain.
if you get error message, check the CORS config on the server side.
在大多数住房服务中,只需在目标服务器文件夹上的 .htaccess 中添加以下内容:
Header set Access-Control-Allow-Origin 'https://your.site.folder'
In most housing services just add in the .htaccess on the target server folder this:
Header set Access-Control-Allow-Origin 'https://your.site.folder'
我也有同样的问题。在我的情况下,我通过将
timestamp
的添加参数添加到我的URL中来修复。即使是我要访问的服务器也不需要这一点。示例yoururl.com/yourdocument?timestamp=1234567
注意:我使用了EPOS时间戳
I had the same issue. In my case i fixed it by adding addition parameter of
timestamp
to my URL. Even this was not required by the server I was accessing.Example yoururl.com/yourdocument?timestamp=1234567
Note: I used epos timestamp
带有附加标头的“获取”请求转换为“选项”请求。所以Cors策略出现问题。您必须向您的服务器实施“选项”请求。 关于服务器端的 Cors 策略,您需要在服务器端允许 Cors 策略。 对于 Nodejs 服务器:详细信息
Java 与 Angular 集成:详细信息
"Get" request with appending headers transform to "Options" request. So Cors policy problems occur. You have to implement "Options" request to your server. Cors Policy about server side and you need to allow Cors Policy on your server side. For Nodejs server:details
For Java to integrate with Angular:details
您应该使CORS能够正常工作。
You should enable CORS to get it working.