XMLHttpRequest 无法加载 XXX 否“Access-Control-Allow-Origin”标头

发布于 2025-01-10 12:07:37 字数 427 浏览 0 评论 0原文

太长;博士;关于同源策略

我有一个 Grunt 进程,它启动express.js 服务器的实例。直到现在它开始提供空白页面,并在 Chrome(最新版本)的开发人员控制台的错误日志中显示以下内容时,这一切都工作得很好:

XMLHttpRequest 无法加载 https://www.example.com/ 请求中不存在“Access-Control-Allow-Origin”标头 资源。因此,不允许访问源 'http://localhost:4300'。

是什么阻止我访问该页面?

tl;dr; About the Same Origin Policy

I have a Grunt process which initiates an instance of express.js server. This was working absolutely fine up until just now when it started serving a blank page with the following appearing in the error log in the developer's console in Chrome (latest version):

XMLHttpRequest cannot load https://www.example.com/
No 'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://localhost:4300' is therefore not allowed access.

What is stopping me from accessing the page?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

随梦而飞# 2025-01-17 12:07:37

tl;dr — 当您想要(主要)使用客户端 JS 从不同的服务器读取数据时,您需要包含数据的服务器向需要数据的代码授予显式权限。

最后有一个摘要,答案中有标题,以便更容易找到相关部分。不过,建议阅读所有内容,因为它为理解原因提供了有用的背景,使了解如何在不同情况下如何应用变得更容易。

关于同源策略

这是同源策略 。它是浏览器实现的一项安全功能。

您的特定案例显示了它是如何为 XMLHttpRequest 实现的(如果您使用 fetch,您将获得相同的结果),但它也适用于其他事物(例如加载到 或加载到 中的文档),只是实现方式略有不同。

证明 SOP 需求的标准场景可以用三个角色来演示:

  • Alice 是一个人使用网络浏览器
  • Bob 运行一个网站(在您的示例中为 https://www.example.com/
  • Mallory 运行一个网站(http://localhost:4300 在你的例子)

爱丽丝登录到鲍勃的网站并且那里有一些机密数据。也许是公司内部网(只能通过 LAN 上的浏览​​器访问),或者她的网上银行(只能通过输入用户名和密码后获得的 cookie 访问)。

Alice 访问 Mallory 的网站,该网站包含一些 JavaScript,导致 Alice 的浏览器向 Bob 的网站发出 HTTP 请求(通过她的 IP 地址和 cookie 等)。这可以像使用 XMLHttpRequest 并读取 responseText 一样简单。

浏览器的同源策略阻止 JavaScript 读取 Bob 网站返回的数据(Bob 和 Alice 不希望 Mallory 访问该网站)。 (请注意,例如,您可以跨源使用 元素显示图像,因为图像的内容不会暴露给 JavaScript(或 Mallory)……除非您将 canvas 放入混合,在这种情况下您生成同源违规错误)。


为什么同源策略适用,而您认为它不应该适用

对于任何给定的 URL,可能不需要 SOP。这种情况的几个常见场景是:

  • Alice、Bob 和 Mallory 是同一个人。
  • Bob 提供的是完全公开的信息

……但是浏览器无法知道上述任一信息是否属实,因此信任不是自动的,并且应用了 SOP。在浏览器将从 Bob 收到的数据提供给其他网站之前,必须明确授予许可。


为什么同源策略适用于网页中的 JavaScript,但

在网页之外

几乎不适用浏览器扩展*、浏览器开发人员工具中的“网络”选项卡以及 Postman 等应用程序都是安装软件。它们不会仅仅因为您访问了另一个网站就将数据从一个网站传递到属于另一网站的 JavaScript。。安装软件通常需要更明智的选择。

不存在被视为风险的第三方(马洛里)。

* 浏览器扩展确实需要仔细编写以避免跨源问题。 请参阅 Chrome 文档示例

网页内部

大多数时候,仅在网页上显示某些内容时不会有大量信息泄露。

如果您使用 元素加载图像,则该图像会显示在页面上,但向 Mallory 暴露的信息很少。 JavaScript 无法读取图像(除非您使用 crossOrigin 属性通过 CORS 显式启用请求权限),然后将其复制到她的服务器。

也就是说,一些信息确实泄露了,引用 Domenic Denicola(Google 的):

网络的基本安全模型是同源策略。我们
在该安全之前,该规则有几个遗留的例外情况
模型已经就位,脚本标签是最令人震惊的标签之一
并且最危险。 (请参阅各种“JSONP”攻击。)

许多年前,也许随着 XHR 或网络字体的引入(我
记不清了),我们在沙子上画了一条线,并说没有新的
Web 平台功能将打破同源政策。现有的
功能需要继承并经过精心打磨
以及经常被利用的异常,为了不破坏网络,
但我们当然不能在我们的安全策略中添加更多漏洞。

这就是为什么您需要 CORS 权限才能跨源加载字体。


为什么无需使用 JS 读取数据即可在页面上显示数据

在许多情况下,Mallory 的网站可能会导致浏览器从第三方获取数据并显示它(例如,通过添加 元素来显示图像)。不过 Mallory 的 JavaScript 不可能读取该资源中的数据,只有 Alice 的浏览器和 Bob 的服务器可以做到这一点,因此它仍然是安全的。


CORS

错误消息中引用的 Access-Control-Allow-Origin HTTP response 标头是 CORS 标准,允许 Bob 明确授予 Mallory 网站通过 Alice 浏览器访问数据的权限。

基本的实现只包括:

Access-Control-Allow-Origin: *

……在响应标头中,以允许任何网站读取数据。

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

…将只允许特定站点访问它,Bob 可以根据 Origin 请求 标头动态生成它,以允许多个(但不是所有)站点访问它。

Bob 设置响应标头的具体情况取决于 Bob 的 HTTP 服务器和/或服务器端编程语言。 Node.js/Express.js 的用户应使用文档完善的 CORS 中间件。其他平台的用户应该看看各种常见配置的指南集合,这可能会有所帮助。

模型所在位置应用 CORS 规则

注意:某些请求很复杂,会发送 预检 选项请求,服务器必须在浏览器将发送 JS 想要发出的 GET/POST/PUT/Whatever 请求。仅将 Access-Control-Allow-Origin 添加到特定 URL 的 CORS 实现通常会因此而出错。


显然,只有在以下情况下,Bob 才会通过 CORS 授予权限:

  • 数据不是私有的或
  • Mallory 受信任

如何添加这些标头?

这取决于您的服务器端环境。

如果可以的话,请使用专门用于处理 CORS 的库,因为它们将为您提供简单的选项,而不必手动处理所有内容。

Enable-Cors.org 提供了您可能会觉得有用的特定平台和框架的文档列表。

但我不是鲍勃!

Mallory 没有标准机制来添加此标头,因为它必须来自 Bob 的网站,而她无法控制该网站。

如果 Bob 正在运行公共 API,则可能有一种机制可以打开 CORS(可能通过以某种方式格式化请求,或者在登录到 Bob 站点的开发人员门户站点后使用配置选项)。但这必须是 Bob 实现的机制。 Mallory 可以阅读 Bob 网站上的文档以查看是否有可用的内容,或者她可以与 Bob 交谈并要求他实施 CORS。


提及“预检响应”的错误消息

某些跨源请求是 预检

当(粗略地说)您尝试发出以下跨域请求时,就会发生这种情况:

  • 包含 cookie 之类的凭据
  • 无法使用常规 HTML 表单生成(例如,设置了无法在表单的 enctype 或其他一些请求标头)。

如果您正确地执行了需要预检的操作,

那么在这些情况下,此答案的其余部分仍然适用,但您还需要确保服务器可以侦听预检请求(这将是 OPTIONS(而不是 GETPOST 或您尝试发送的任何内容)并使用正确的 Access-Control-Allow 响应它-Origin 标头还Access-Control-Allow-MethodsAccess-Control-Allow-Headers 允许您的特定 HTTP 方法或标头

如果您错误地触发了预检

有时人们会犯错误。当尝试构建 Ajax 请求时,有时会触发预检的需要。如果 API 设计为允许跨源请求,但不需要任何需要预检的内容,那么这可能会中断访问

。这包括:

  • 尝试将 Access-Control-Allow-Origin 和其他 CORS 响应标头放在请求中。这些不属于请求,不做任何有用的事情(您可以授予自己权限的权限系统有什么意义?),并且必须仅出现在响应中。
  • 尝试将 Content-Type: application/json 标头放在没有要描述内容的请求正文的 GET 请求上(通常当作者混淆 Content-Type接受)。

在这两种情况下,删除额外的请求标头通常足以避免预检的需要(这将解决与支持简单请求但不支持预检请求的 API 通信时的问题)。


不透明响应(no-cors 模式)

有时您需要发出 HTTP 请求,但不需要读取响应。例如,如果您要将日志消息发布到服务器进行记录。

如果您使用fetch API< /a> (而不是 XMLHttpRequest),那么您可以将其配置为不尝试使用 CORS。

请注意,这不会让您执行任何需要 CORS 执行的操作您将无法阅读回复。您将无法提出需要预检的请求。

它可以让您发出简单的请求,而不会看到响应,并且不会在开发人员控制台中填充错误消息。

当您使用 fetch 发出请求并且没有获得使用 CORS 查看响应的权限时,Chrome 会给出错误消息,解释了具体操作方法:

从源“https://example.net”获取“https://example.com/”的访问已被 CORS 策略阻止:否请求的资源上存在“Access-Control-Allow-Origin”标头。如果不透明响应满足您的需求,请将请求模式设置为“no-cors”以在禁用 CORS 的情况下获取资源。

因此:

fetch("http://example.com", { mode: "no-cors" });

CORS

JSONP

的替代方案Bob 还可以使用 JSONP 之类的 hack 来提供数据这就是 CORS 出现之前人们进行跨源 Ajax 的方式。

它的工作原理是以 JavaScript 程序的形式呈现数据,并将数据注入 Mallory 的页面。

它要求 Mallory 信任 Bob 不会提供恶意代码。

请注意共同的主题:提供数据的站点必须告诉浏览器第三方站点可以访问它发送到浏览器的数据。

由于 JSONP 的工作原理是附加一个

将两个资源移动到一个源

如果 JS 运行的 HTML 文档和所请求的 URL 位于同一源(共享相同的方案、主机名和端口),则同源策略默认授予权限。不需要 CORS。

代理

Mallory可以使用服务器端代码来获取数据(然后她可以像往常一样通过 HTTP 将数据从她的服务器传递到 Alice 的浏览器)。

它将:

  • 添加 CORS 标头
  • 将响应转换为
  • 与 HTML 文档同源的

JSONP可以编写服务器端代码由第三方(例如 CORS Anywhere)托管。请注意这对隐私的影响:第三方可以监控谁在其服务器上代理了什么。

鲍勃不需要授予任何权限即可发生这种情况。

这里不存在任何安全隐患,因为这只是 Mallory 和 Bob 之间的事情。 Bob 无法认为 Mallory 是 Alice,也无法向 Mallory 提供应在 Alice 和 Bob 之间保密的数据。

因此,Mallory 只能使用此技术来读取公共数据。

但请注意,从他人网站获取内容并自行展示可能会侵犯版权,并使您面临法律诉讼。

编写 Web 应用程序以外的内容

正如“为什么同源策略仅适用于网页中的 JavaScript”部分所述,您可以通过不在网页中编写 JavaScript 来避免 SOP。

这并不意味着您不能继续使用 JavaScript 和 HTML,但您可以使用其他一些机制(例如 Node-WebKit 或 PhoneGap)来分发它。

浏览器扩展

浏览器扩展可以在应用同源策略之前在响应中注入 CORS 标头。

这些对于开发很有用,但对于生产站点来说并不实用(要求站点的每个用户安装禁用其浏览器安全功能的浏览器扩展是不合理的)。

它们也往往只处理简单的请求(在处理预检选项请求时失败)。

拥有适当的开发环境和本地开发服务器
通常是更好的方法。


其他安全风险

请注意,SOP / CORS 不能缓解 XSSCSRF,或 SQL注入攻击,需要独立处理。


摘要

  • 您在的客户端代码中无法执行任何操作来启用对其他人服务器的CORS 访问。
  • 如果您控制服务器,则会发出请求:向其添加 CORS 权限。
  • 如果您与控制它的人很友好:让他们为其添加 CORS 权限。
  • 如果它是一项公共服务(请记住,大多数第三方 API 设计为仅通过服务器端代码进行交互,并且不支持 CORS,但对于支持 CORS 的 API 除外):
    • 阅读他们的 API 文档,了解他们如何使用客户端 JavaScript 访问它:
      • 他们可能会告诉您使用特定的网址
      • 他们可能支持 JSONP 而不是 CORS
      • 它们可能根本不支持客户端代码的跨源访问(这可能是出于安全考虑而做出的故意决定,特别是当您必须在每个请求中传递个性化 API 密钥时)。
    • 确保您没有触发不需要的预检请求。 API 可能会授予简单请求的权限,但不会授予预检请求的权限。
  • 如果上述情况都不适用:让浏览器与您的服务器通信,然后让您的服务器从其他服务器获取数据并将其传递。 (还有第三方托管服务将 CORS 标头附加到您可以使用的可公开访问的资源)。

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:

  • Alice is a person with a web browser
  • Bob runs a website (https://www.example.com/ in your example)
  • Mallory runs a website (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 the responseText.

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:

  • Alice, Bob, and Mallory are the same person.
  • Bob is providing entirely public information

… 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 a crossOrigin 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):

The web's fundamental security model is the same origin policy. We
have several legacy exceptions to that rule from before that security
model was in place, with script tags being one of the most egregious
and most dangerous. (See the various "JSONP" attacks.)

Many years ago, perhaps with the introduction of XHR or web fonts (I
can't recall precisely), we drew a line in the sand, and said no new
web platform features would break the same origin policy. The existing
features need to be grandfathered in and subject to carefully-honed
and oft-exploited exceptions, for the sake of not breaking the web,
but we certainly can't add any more holes to our security policy.

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:

Access-Control-Allow-Origin: *

… in the response headers to permit any website to read the data.

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

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

Model of where CORS rules are applied

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:

  • The data was not private or
  • Mallory was trusted

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:

  • Includes credentials like cookies
  • Couldn't be generated with a regular HTML form (e.g. sets a Content-Type that you couldn't use in a form's 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 not GET, POST, or whatever you were trying to send) and respond to it with the right Access-Control-Allow-Origin header but also Access-Control-Allow-Methods and Access-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:

  • trying to put 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.
  • trying to put a Content-Type: application/json header on a GET request that has no request body the content of which to describe (typically when the author confuses Content-Type and Accept).

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 than XMLHttpRequest), 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:

Access to fetch at 'https://example.com/' from origin 'https://example.net' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

Thus:

fetch("http://example.com", { mode: "no-cors" });

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:

  • add CORS headers
  • convert the response to JSONP
  • exist on the same origin as the HTML document

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

  • There is nothing you can do in your client-side code that will enable CORS access to someone else's server.
  • If you control the server the request is being made to: Add CORS permissions to it.
  • If you are friendly with the person who controls it: Get them to add CORS permissions to it.
  • If it is a public service then (keeping in mind that most third-party APIs are designed to be interacted with only by your server-side code and do not support CORS but for those that are):
    • Read their API documentation to see what they say about accessing it with client-side JavaScript:
      • They might tell you to use specific URLs
      • They might support JSONP instead of CORS
      • They might not support cross-origin access from client-side code at all (this might be a deliberate decision on security grounds, especially if you have to pass a personalized API Key in each request).
    • Make sure you aren't triggering a preflight request you don't need. The API might grant permission for simple requests but not preflighted requests.
  • If none of the above apply: Get the browser to talk to your server instead, and then have your server fetch the data from the other server and pass it on. (There are also third-party hosted services that attach CORS headers to publically accessible resources that you could use).
温暖的光 2025-01-17 12:07:37

目标服务器必须允许跨源请求。为了允许它通过express,只需处理http选项请求:

app.options('/url...', function(req, res, next){
   res.header('Access-Control-Allow-Origin', "*");
   res.header('Access-Control-Allow-Methods', 'POST');
   res.header("Access-Control-Allow-Headers", "accept, content-type");
   res.header("Access-Control-Max-Age", "1728000");
   return res.sendStatus(200);
});

Target server must allowed cross-origin request. In order to allow it through express, simply handle http options request :

app.options('/url...', function(req, res, next){
   res.header('Access-Control-Allow-Origin', "*");
   res.header('Access-Control-Allow-Methods', 'POST');
   res.header("Access-Control-Allow-Headers", "accept, content-type");
   res.header("Access-Control-Max-Age", "1728000");
   return res.sendStatus(200);
});
魄砕の薆 2025-01-17 12:07:37

因为在接受的答案中没有提到这一点。

  • 这个问题的情况并非如此,但可能会帮助其他人搜索该问题。
  • 您可以在客户端代码中执行此操作,以防止某些情况下出现 CORS 错误。

您可以使用简单请求
为了执行“简单请求”,请求需要满足几个条件。例如只允许 POSTGETHEAD 方法,以及只允许某些给定的 headers(您可以找到所有条件 此处)。

如果您的客户端代码没有在请求中使用固定值显式设置受影响的标头(例如“接受”),则可能会出现某些客户端使用某些“非标准”值自动设置这些标头的情况,从而导致服务器不接受它作为简单请求 - 这会给你一个 CORS 错误。

As this isn't mentioned in the accepted answer.

  • This is not the case for this exact question, but might help others that search for that problem
  • This is something you can do in your client-code to prevent CORS errors in some cases.

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 and HEAD 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.

残月升风 2025-01-17 12:07:37

这是由于 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

故事↓在人 2025-01-17 12:07:37

这个 CORS 问题没有进一步阐述(由于其他原因)。

我目前因不同原因遇到此问题。
我的前端也返回“Access-Control-Allow-Origin”标头错误。

只是我指出了错误的 URL,因此该标头没有正确反映(我一直认为它确实反映了)。本地主机(前端)->调用非安全 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.

不如归去 2025-01-17 12:07:37

我在 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 of https://. So there was nothing to fix, just had to go to the same site using https.

人事已非 2025-01-17 12:07:37

这个bug花了我2天时间。我检查了服务器日志,浏览器 Chrome/Edge 和服务器之间的预检选项请求/响应正常。主要原因是 XHTMLRequest 的 GET/POST/PUT/DELETE 服务器响应还必须具有以下标头:

access-control-allow-origin: origin  

“origin”位于请求标头中(浏览器将添加它为您提出要求)。例如:

Origin: http://localhost:4221

您可以添加如下响应标头以接受所有请求:

access-control-allow-origin: *  

或特定请求的响应标头,例如:

access-control-allow-origin: http://localhost:4221 

浏览器中的消息不清楚:“...请求的资源”

请注意:
CORS 对于本地主机来说效果很好。不同的端口意味着不同的域。
如果收到错误消息,请检查服务器端的 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:

access-control-allow-origin: origin  

"origin" is in the request header (Browser will add it to request for you). for example:

Origin: http://localhost:4221

you can add response header like the following to accept for all:

access-control-allow-origin: *  

or response header for a specific request like:

access-control-allow-origin: http://localhost:4221 

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.

请止步禁区 2025-01-17 12:07:37

在大多数住房服务中,只需在目标服务器文件夹上的 .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'

大姐,你呐 2025-01-17 12:07:37

我有同样的问题。就我而言,我通过在 URL 中添加 timestamp 附加参数来修复此问题。即使我访问的服务器也不需要这样做。

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

心凉 2025-01-17 12:07:37

带有附加标头的“获取”请求转换为“选项”请求。所以Cors策略出现问题。您必须向您的服务器实施“选项”请求。 关于服务器端的 Cors 策略,您需要在服务器端允许 Cors 策略。 对于 Nodejs 服务器:详细信息

app.use(cors)

Java 与 Angular 集成:详细信息

@CrossOrigin(origins = "http://localhost:4200")

"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

app.use(cors)

For Java to integrate with Angular:details

@CrossOrigin(origins = "http://localhost:4200")
梦中楼上月下 2025-01-17 12:07:37

您应该启用 CORS 才能使其正常工作。

You should enable CORS to get it working.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文