Javascript 当 http://localhost 是源时的致命 CORS

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10883211/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 03:24:36  来源:igfitidea点击:

Deadly CORS when http://localhost is the origin

javascripthtmlcorsxmlhttprequestxmlhttprequest-level2

提问by whadar

I am stuck with this CORS problem, even though I set the server (nginx/node.js) with the appropriate headers.

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

I can see in Chrome Network pane -> Response Headers:

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

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

which should do the trick.

这应该可以解决问题。

Here's the code that I now use to test:

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

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

I get

我得到

XMLHttpRequest cannot load http://stackoverflow.com/. Origin http://localhostis not allowed by Access-Control-Allow-Origin.

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

I suspect it's a problem in the client script and not server configuration...

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

回答by Beau

Chrome does not support localhost for CORS requests(a bug opened in 2010, marked WontFix in 2014).

Chrome不支持 localhost 的 CORS 请求(一个在 2010 年打开的错误,在 2014 年标记为 WontFix)。

To get around this you can use a domain like lvh.me(which points at 127.0.0.1 just like localhost) or start chrome with the --disable-web-securityflag (assuming you're just testing).

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

回答by Hanxue

Per @Beau's answer, Chrome does not support localhost CORS requests, and there is unlikely any change in this direction.

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

I use the Allow-Control-Allow-Origin: * Chrome Extensionto go around this issue. The extension will add the necessary HTTP Headers for CORS:

我使用Allow-Control-Allow-Origin: * Chrome 扩展来解决这个问题。该扩展将为 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>

The source code is published on Github.

源代码被发布在Github

Note that the extension filter all URLs by default. This may break some websites (for example: Dropbox). I have changed it to filter only localhostURLs with the following URL filter

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

*://localhost:*/*

回答by greensuisse

The real problem is that if we set -Allow-for all request (OPTIONS& POST), Chrome will cancel it. The following code works for me with POSTto LocalHost with Chrome

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

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

回答by Brad

Chrome will make requests with CORS from a localhostorigin just fine. This isn't a problem with Chrome.

Chrome 将使用来自localhost源的CORS 发出请求。这不是 Chrome 的问题。

The reason you can't load http://stackoverflow.comis that the Access-Control-Allow-Originheaders weren't allowing your localhostorigin.

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

回答by kaleazy

Quick and dirty Chrome extension fix:

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

Moesif Orign & CORS Changer

Moesif Orign & CORS 转换器

However, Chrome does support cross-origin requests from localhost. Make sure to add a header for Access-Control-Allow-Originfor localhost.

但是,Chrome 确实支持来自 localhost 的跨域请求。确保Access-Control-Allow-Originlocalhost.

回答by Juri Sinitson

I decided not to touch headers and make a redirect on the server side instead and it woks like a charm.

我决定不接触标题,而是在服务器端进行重定向,它看起来很迷人。

The example below is for the current version of Angular (currently 9) and probably any other framework using webpacks DevServer. But I think the same principle will work on other backends.

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

So I use the following configuration in the file proxy.conf.json:

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

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

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

In case of Angular I serve with that configuration:

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

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

I prefer to use the proxy in the serve command, but you may also put this configuration to angular.jsonlike this:

我更喜欢在 serve 命令中使用代理,但您也可以将此配置放入angular.json 中,如下所示:

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

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

See also:

也可以看看:

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

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

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

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

回答by daniel p

None of the extensions worked for me, so I installed a simple local proxy. In my case https://www.npmjs.com/package/local-cors-proxyIt is a 2-minute setup:

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

(from their site)

(来自他们的网站)

npm install -g local-cors-proxy

API endpoint that we want to request that has CORS issues: https://www.yourdomain.ie/movies/list

Start Proxy: lcp --proxyUrl https://www.yourdomain.ie

Then in your client code, new API endpoint: http://localhost:8010/proxy/movies/list

npm install -g local-cors-proxy

我们要请求的具有 CORS 问题的 API 端点: https://www.yourdomain.ie/movies/list

启动代理: lcp --proxyUrl https://www.yourdomain.ie

然后在您的客户端代码中,新的 API 端点: http://localhost:8010/proxy/movies/list

Worked like a charm for me: your app calls the proxy, who calls the server. Zero CORS problems.

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