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

时间:2012-06-04 14:42:28

标签: javascript html5 cors xmlhttprequest xmlhttprequest-level2

即使我使用适当的标头设置服务器(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 cannot load http://stackoverflow.com/. Origin http://localhost is not allowed by Access-Control-Allow-Origin.

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

12 个答案:

答案 0 :(得分:169)

Chrome does not support localhost for CORS requests(自2010年以来的一个漏洞)。

要解决此问题,您可以使用lvh.me之类的域名(与localhost一样指向127.0.0.1)或使用--disable-web-security标记启动chrome(假设您只是在测试)。< / p>

答案 1 :(得分:38)

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

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

过滤 localhost 网址
*://localhost:*/*

答案 2 :(得分:19)

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

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

答案 3 :(得分:7)

这些扩展都不适合我,因此我安装了一个简单的本地代理。就我而言,https://www.npmjs.com/package/local-cors-proxy 这是2分钟的设置:

(来自他们的站点)

npm install -g local-cors-proxy
我们要请求的

API端点存在CORS问题: https://www.yourdomain.ie/movies/list

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

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

对我来说就像是一种魅力:您的应用程序调用代理,后者又调用服务器。零CORS问题。

答案 4 :(得分:3)

Chrome可以很好地发起来自localhost的带有CORS的请求。 Chrome没问题。

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

答案 5 :(得分:1)

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

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

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

答案 6 :(得分:0)

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

IBM Informix page

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

答案 7 :(得分:0)

我决定不碰标题,而是在服务器端进行重定向,它像魔咒一样醒来。

下面的示例适用于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

答案 8 :(得分:0)

同意!应该在服务器端启用CORS,以解决问题。但是...

对我而言,情况是:

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

只是测试

在尝试了上述所有步骤后,我被迫禁用了chrome上的网络安全和站点隔离测试,并指定了用户数据目录(尝试跳过此步骤,因此无效)。

对于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"

这终于奏效了!希望这会有所帮助!

答案 9 :(得分:0)

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

  • Access-Control-Allow-Origin:'*'(或网站域)
  • 访问控制允许方法:'POST、GET、OPTIONS'
    • 这是告诉 chrome 我们现在可以发送 POST/GET 请求的预检响应
  • 访问控制允许标题:'内容类型'
    • 不确定是否有必要,但它告诉 chrome 该请求可以包含一个 Content-Type 标头

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

  1. OPTIONS 标头,其中包括
    • access-control-request-method: 'POST'(或您请求的任何 http 方法)
    • 来源:'http://localhost:3000'(网站域)
    • referer: 'http://localhost:3000/'(我相信这是完整的网站路径)
    • sec-fetch-mode: 'cors'
    • sec-fetch-site: '跨站点'

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

  1. 实际请求,例如:POST 标头,其中包括
    • 内容类型:'应用程序/json'
    • 起源:同上
    • referer:同上

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

答案 10 :(得分:-1)

前几天我和cors一起做噩梦,所以我切换了编程范例。

对于我的Web应用程序,我正在开发中,最终将其部署到生产中,在这种情况下,我使用的是Heroku。为了处理服务器端之类的东西,例如http,我使用Postman测试所有的http路由,邮递员不会被cors阻塞。

完成单元测试并验证后,我将服务器部署到Heroku,然后在客户端上工作。这样,客户端就会向不在其他位置且未收到cors的服务器发出请求。

答案 11 :(得分:-2)

解决方案是安装扩展程序,以解除Chrome的限制,例如:

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