仅当有标头时,Chrome 中的 CORS 请求才会失败

Posted

技术标签:

【中文标题】仅当有标头时,Chrome 中的 CORS 请求才会失败【英文标题】:CORS request fails in Chrome only if has headers 【发布时间】:2013-01-07 16:45:06 【问题描述】:

我正在尝试向使用会话密钥进行授权的外部应用程序服务器发送简单的 CORS 请求。

$.ajax(
    type: "GET",
    url: "https://192.168.1.72:8442/api/file/",
    headers: "Authorization": "3238562439e44fcab4036a24a1e6b0fb"
);

它在 Firefox 18、Opera 12.12 和 Rekonq 2.0(也使用 WebKit)中运行良好,但在 Google Chrome 中无法运行(尝试过 21 和 24 版)。在 Google Chrome 中,它显示 OPTIONS Resource 无法在 Network Inspector 中加载,并且应用程序服务器没有收到任何请求。我试过 jQuery 1.8.3 和 1.9.0。

Request URL:https://192.168.1.72:8442/api/file/
Request Headers
Access-Control-Request-Headers:accept, authorization, origin
Access-Control-Request-Method:GET
Cache-Control:no-cache
Origin:https://192.168.1.72:8480
Pragma:no-cache

如果我从请求中删除标头,那么我也会在 Google Chrome 中收到 401,并且它能够在应用程序服务器上禁用授权的情况下访问资源。发送哪些标头并不重要。我能够发送的唯一标题是“Content-Type”:“plain/text”。所有其他标头名称/值在 Google Chrome 中都会出错,但在我上面提到的所有浏览器中都可以使用。

为什么谷歌浏览器不处理 CORS 请求中的标头?

【问题讨论】:

用普通的a试试authorization 您能列出 OPTIONS 请求的请求和响应标头吗?服务器应该响应以下内容:Access-Control-Allow-Origin: *Access-Control-Allow-Methods: GET, PUT, POST, DELETEAccess-Control-Allow-Headers: accept, authorization, origin @monsur:我已经有了所有这些标题。我也尝试添加更多允许的标头和方法,但没有帮助。 Chrome 给你的错误是什么? @monsur:在网络检查器中:OPTIONS Resource failed to load。 Ajax 错误响应:"readyState":0,"responseText":"","status":0,"statusText":"error" 【参考方案1】:

服务器端: 服务器应设置标头“Access-Control-Allow-Credentials”,并在“Access-Control-Allow-Headers”中设置允许的标头。

客户端:您可以在 $.ajax() 中设置 xhrFields,而不是显式传递 Auth 标头。

xhrFields: 
    withCredentials: true 

更多详情here.

【讨论】:

withCredentials 似乎用于 cookie 或基本身份验证。我只想让请求标头在 Chrome 中工作。【参考方案2】:

我在我的 api 服务器上使用自签名证书,这似乎是问题所在。我发现如果我使用 --disable-web-security 选项启动 Google Chrome,那么带有请求标头的 CORS 就可以工作。如果没有--disable-web-security,我可以将 CORS 请求发送到自签名 api 服务器,但不能添加任何标头(Content-Type 除外)。

【讨论】:

一个域连接到另一个域(都使用 http)时会出现同样的问题。您的 --disable-web-security 选项也可以解决这种情况。我相信 那个 错误是 EventSource 特有的,可能会在 Chrome 26 中修复。但是 --disable-web-security 没有修复自签名证书 HTTPS 问题(无论是使用 EventSource 还是 XMLHttpResponse),至少在铬 25。【参考方案3】:

这是 Google Chrome 中的一个错误:http://code.google.com/p/chromium/issues/detail?id=96007。

【讨论】:

仅供参考,该错误已于 2015 年 10 月关闭。 我有类似的问题,我的应用程序是使用 Angular 7 构建的。我正在对 BPMS 服务器进行 ajax 调用,该服务器在 IE 中运行良好,但在 Chrome 中出现 CORS 错误。但是,当我将 ajax url 复制到 Chrome 浏览器时,我拥有所有数据。有人可以帮忙吗?【参考方案4】:

我发现 Access-Control-Allow-Headers: * 应该只为“OPTIONS”请求设置。 如果您为 POST 请求返回它,则浏览器会取消该请求(至少对于 chrome)

以下 php 代码适用于我

// Allow CORS
header("Access-Control-Allow-Origin: *");
header('Access-Control-Allow-Credentials: true');    
header("Access-Control-Allow-Methods: GET, POST, OPTIONS"); 

// Access-Control headers are received during OPTIONS requests
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') 
  header("Access-Control-Allow-Headers: *");

我发现类似的问题有一些误导性的回答: - 服务器线程说这是 2 年的 chrome 错误:Access-Control-Allow-Headers 与 localhost 不匹配。错了:我可以通过 Post 正常使用 CORS 到我的本地服务器 - Access-Control-Allow-Headers 接受通配符。也错了,通配符对我有用(我只用 Chrome 测试过)

这需要我半天时间才能弄清楚问题。

快乐编码

【讨论】:

这篇文章的第一句话救了我。谢谢!

以上是关于仅当有标头时,Chrome 中的 CORS 请求才会失败的主要内容,如果未能解决你的问题,请参考以下文章

只有在回调/异步函数内部时,Axios 请求才会收到 CORS 错误

调用 AWS Lambda 时,Chrome 忽略 Access-Control-Allow-Origin 标头并因预检错误导致 CORS 失败

Safari 中的 CORS 错误,而不是 Chrome

当且仅当有新的提交时,如何在一天中的特定时间构建 XCode 机器人?

在 Node.js Express.js 服务器中添加标头后,Chrome 中仍然出现 CORS 错误

移动 Chrome 上的 CORS Allow-Access-Control-Origin