ChatGPT解决这个技术问题 Extra ChatGPT

为什么我的 http://localhost CORS 来源不起作用?

即使我为服务器(nginx/node.js)设置了适当的标头,我也遇到了这个 CORS 问题。

我可以在 Chrome 网络窗格中看到 -> 响应标头:

Access-Control-Allow-Origin:http://localhost

这应该可以解决问题。

这是我现在用来测试的代码:

var xhr = new XMLHttpRequest();
xhr.onload = function() {
   console.log('xhr loaded');
};
xhr.open('GET', 'http://stackoverflow.com/');
xhr.send();

我明白了

XMLHttpRequest 无法加载 http://stackoverflow.com/。 Access-Control-Allow-Origin 不允许来源 http://localhost。

我怀疑这是客户端脚本中的问题,而不是服务器配置中的问题...

不,stackoverflow.com 需要设置此标头,而不是您。 :X。否则,同源政策的意义何在。
尝试访问您设置的服务器而不是堆栈溢出。 ;)
哦!有没有办法告诉 chrome(或其他浏览器),即使当我的来源是 localhost 时标题丢失也能获取资源?
在 Chrome(20.0.1132.57,Windows 7)中运行您的代码,工作正常。
如果您将 localhost 与端口一起使用,则此答案对我有用 serverfault.com/a/673551/238261

B
Beau

Chrome does not support localhost for CORS requests(2010 年发现的错误,2014 年标记为 WontFix)。

为了解决这个问题,您可以使用像 localho.st 这样的域(它指向 127.0.0.1,就像 localhost 一样)或使用 --disable-web-security 标志启动 chrome(假设您只是在测试)。


@greensuisse - 它没有发布到本地主机。这是从本地主机发布的问题。
该错误无效(并且已被标记为 - crbug.com/67743#c17)。 Esailija's comment 是正确的,将这些标头添加到 localhost 不会神奇地让您访问所有其他站点。需要使用这些标头提供服务的是远程站点。
其他选项:编辑您的主机文件,使 local.[mysite].com 指向 127.0.0.1,然后让您的 CORS 文件允许 *.[mysite].com
我在使用 FireFox 时遇到了同样的问题。我只能在 Edge 上成功!不错的帖子,太棒了! :)
请参阅下面的@Molumby 评论“Chrome 100% 确实支持与本地主机之间的跨域请求......”
J
Jonathan Arbely

根据@Beau 的回答,Chrome 不支持 localhost CORS 请求,并且在这个方向上不太可能有任何改变。

我使用 Allow-Control-Allow-Origin: * Chrome Extension 来解决这个问题。该扩展将为 CORS 添加必要的 HTTP 标头:

Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: "GET, PUT, POST, DELETE, HEAD, OPTIONS"
Access-Control-Expose-Headers: <you can add values here>

source code is published on Github

请注意,扩展默认过滤所有 URL。这可能会破坏某些网站(例如:Dropbox)。我已将其更改为仅使用以下 URL 过滤器过滤 localhost URL

*://localhost:*/*

如果您阅读问题@beau 链接,您会看到 Chrome 100% 确实支持与 localhost 之间的跨域请求。该问题已于 2014 年关闭,因为它无法复制。该线程中的其余噪音是非源服务器配置错误的人(与此处的原始问题一样)。
在 chrome 上对我来说就像魅力一样
此扩展程序不适用于 Access-Control-Allow-Credentials: true,因为它将 Access-Control-Allow-Origin 设置为 * 并且同时具有 true* 被浏览器阻止。如果使用凭据为真,则必须使用非通配符来源。我推荐 Moesif Origins 和 CORS Changer Extension,它允许您根据需要更改标题。
@Chiwda 您可以在此处找到上述内容并加载更多内容:addons.mozilla.org/en-GB/firefox/search/…
d
daniel p

没有一个扩展对我有用,所以我安装了一个简单的本地代理。在我的情况下 https://www.npmjs.com/package/local-cors-proxy 这是一个 2 分钟的设置:

(来自他们的网站)

我们要请求的具有 CORS 问题的 npm install -g local-cors-proxy API 端点:https://www.yourdomain.ie/movies/list 启动代理:lcp --proxyUrl https://www.yourdomain.ie然后在您的客户端代码中,新的 API 端点:http://localhost:8010/proxy/movies/list

对我来说就像一个魅力:你的应用程序调用代理,代理调用服务器。零 CORS 问题。


为我工作(http://localhost:81/sse 的 http 服务器):lcp --proxyUrl http://localhost:81/sse。在代码中更改为 http://localhost:8010/proxy/sse(在命令行中由 lcp.
这对我来说就像一个魅力。非常感谢。
Y
Yves M.

真正的问题是,如果我们为所有请求(OPTIONSPOST)设置 -Allow-,Chrome 将取消它。以下代码适用于我使用 Chrome 到 LocalHost 的 POST

<?php
if (isset($_SERVER['HTTP_ORIGIN'])) {
    //header("Access-Control-Allow-Origin: {$_SERVER['HTTP_ORIGIN']}");
    header("Access-Control-Allow-Origin: *");
    header('Access-Control-Allow-Credentials: true');    
    header("Access-Control-Allow-Methods: GET, POST, OPTIONS"); 
}   
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
    if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD']))
        header("Access-Control-Allow-Methods: GET, POST, OPTIONS");         
    if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']))
        header("Access-Control-Allow-Headers:{$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}");

    exit(0);
} 
?>

OP 正在使用 nginx/node.js。不是 PHP
B
Brad

Chrome 将从 localhost 源发出 CORS 请求就好了。这不是 Chrome 的问题。

您无法加载 http://stackoverflow.com 的原因是 Access-Control-Allow-Origin 标头不允许您的 localhost 来源。


A
Aditya Patnaik

同意!应该在服务器端启用 CORS 以从根本上解决问题。然而...

对我来说,情况是:

我非常想使用客户端提供的 REST API 在本地测试我的前端(React/Angular/VUE)代码,而无法访问服务器配置。

只是为了测试

在尝试了上述所有不起作用的步骤后,我被迫禁用了 chrome 上的 Web 安全和站点隔离试验,同时指定了用户数据目录(尝试跳过这个,没有用)。

对于 Windows

cd C:\Program Files\Google\Chrome\Application

禁用 Web 安全和站点隔离试验

chrome.exe  --disable-site-isolation-trials --disable-web-security --user-data-dir="PATH_TO_PROJECT_DIRECTORY"

这终于奏效了!希望这可以帮助!


k
kaleazy

快速而肮脏的 Chrome 扩展修复:

Moesif Orign & CORS Changer

但是,Chrome 确实支持来自 localhost 的跨域请求。确保为 localhost 添加 Access-Control-Allow-Origin 的标头。


我在我的 Opera 中添加了这个扩展,现在它已经完成了。我永远无法判断它何时打开和关闭,所以我使用 Firefox 进行工作。和歌剧促进发展。谷歌西装不喜欢它,其他东西也不喜欢。
D
DustinA

我认为我的解决方案可能是最简单的。在我的开发机器上,我在主机文件中添加了一个类似于 http://myfakedomain.notarealtld 的假域,并将其设置为 127.0.0.1。然后我更改了服务器的 CORS 配置(在我的情况下是 S3 存储桶)以允许该域。这样我就可以在 localhost 上使用 Chrome 并且效果很好。

确保您的 CORS 配置考虑了带有端口的整个主机名,即。 http://myfakedomain.notarealtld:3000

您可以在 Linux、Mac 和 Windows 上轻松修改主机文件。


M
Matthew P

Chrome 确实允许本地主机上的 CORS,我使它与 AWS API 网关/lambda 一起工作。在发送 http 请求时查看开发人员工具中的网络选项卡非常有帮助。我的问题是我的 lambda 函数没有处理预检 OPTIONS 请求,只有 POST 和 GET。我通过接受 OPTIONS 请求并确保从我的 API 返回以下标头解决了这个问题:

访问控制允许来源:'*'(或网站域)

Access-Control-Allow-Methods: 'POST, GET, OPTIONS' 这是预检响应告诉 chrome 我们现在可以发送 POST/GET 请求

这是预检响应告诉 chrome 我们现在可以发送 POST/GET 请求

Access-Control-Allow-Headers: 'Content-Type' 不确定这是否必要,但它告诉 chrome 请求可以包含 Content-Type 标头

不确定这是否有必要,但它告诉 chrome 请求可以包含 Content-Type 标头

需要注意的重要一点是浏览器发送了 2 组标头。

包含访问控制请求方法的 OPTIONS 标头:'POST'(或您请求的任何 http 方法)来源:'http://localhost:3000'(网站域)引用者:'http://localhost:3000/ ' (我相信这是完整的网站路径) sec-fetch-mode: 'cors' sec-fetch-site: 'cross-site'

如果对请求 1 的响应是 200 代码并且响应标头包含: 'access-control-allow-methods': 'POST' (或请求中的任何访问控制请求方法),

实际请求,例如:POST headers which includes content-type: 'application/json' origin: 同上 referer: 同上

还有更多的标题,但我认为这些是最重要的。


C
Community

我决定不触摸标题并在服务器端进行重定向,它就像一个魅力。

下面的示例适用于当前版本的 Angular(当前为 9)以及可能使用 webpacks DevServer 的任何其他框架。但我认为同样的原则也适用于其他后端。

所以我在proxy.conf.json文件中使用如下配置:

{
  "/api": {
    "target": "http://localhost:3000",
    "pathRewrite": {"^/api" : ""},
   "secure": false
 }
}

在 Angular 的情况下,我使用该配置:

$ ng serve -o --proxy-config=proxy.conf.json

我更喜欢在 serve 命令中使用代理,但你也可以像这样把这个配置放到 angular.json 中:

"architect": {
  "serve": {
    "builder": "@angular-devkit/build-angular:dev-server",
    "options": {
      "browserTarget": "your-application-name:build",
      "proxyConfig": "src/proxy.conf.json"
    },

也可以看看:

https://www.techiediaries.com/fix-cors-with-angular-cli-proxy-configuration/

https://webpack.js.org/configuration/dev-server/#devserverproxy


B
Bibi Ruiz

解决方案是安装一个扩展来解除 Chrome 所做的阻止,例如:

访问控制-允许-来源-取消阻止 (https://add0n.com/access-control.html?version=0.1.5&type=install)。