jQuery 仅当有标头时,Chrome 中的 CORS 请求才会失败
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14492686/
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
CORS request fails in Chrome only if has headers
提问by Karmo Rosental
I'm trying to send simple CORS request to external application server which uses session key for authorization.
我正在尝试将简单的 CORS 请求发送到使用会话密钥进行授权的外部应用程序服务器。
$.ajax({
type: "GET",
url: "https://192.168.1.72:8442/api/file/",
headers: {"Authorization": "3238562439e44fcab4036a24a1e6b0fb"}
});
It works fine in Firefox 18, Opera 12.12 and Rekonq 2.0 (uses also WebKit) but doesn't work in Google Chrome (tried versions 21 and 24). In Google Chrome it shows OPTIONS Resource failed to load in Network Inspector and application server doesn't get any request. I've tried jQuery 1.8.3 and 1.9.0.
它在 Firefox 18、Opera 12.12 和 Rekonq 2.0(也使用 WebKit)中运行良好,但在 Google Chrome 中不起作用(尝试了 21 和 24 版)。在 Google Chrome 中,它显示 OPTIONS Resource failed to load in 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
If I remove headers from the request then I receive 401 also in Google Chrome and it's able to access the resource in case of authorization is disabled on application server. It doesn't matter which headers are sent. Only header I'm able to send is {"Content-Type": "plain/text"}. All other header names/values give an error in Google Chrome but work in all browsers I mentioned above.
如果我从请求中删除标头,那么我也会在 Google Chrome 中收到 401,并且在应用程序服务器上禁用授权的情况下,它能够访问资源。发送哪些标头并不重要。我只能发送的标题是 {"Content-Type": "plain/text"}。所有其他标题名称/值在 Google Chrome 中都会出错,但适用于我上面提到的所有浏览器。
Why Google Chrome doesn't handle headers in CORS request?
为什么 Google Chrome 不处理 CORS 请求中的标头?
回答by Karmo Rosental
It's a bug in Google Chrome: http://code.google.com/p/chromium/issues/detail?id=96007.
这是谷歌浏览器中的一个错误:http: //code.google.com/p/chromium/issues/detail? id= 96007。
回答by greensuisse
I found that Access-Control-Allow-Headers: * should be set ONLY for "OPTIONS" request. If you return it for POST request then browser cancel the request (at least for chrome)
我发现 Access-Control-Allow-Headers: * 应该只为“OPTIONS”请求设置。如果您为 POST 请求返回它,则浏览器取消请求(至少对于 chrome)
The following PHP code works for me
以下 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: *");
}
I found similar questions with some misleading response: - Server thread says that this is 2 years bug of chrome: Access-Control-Allow-Headers does not match with localhost. It's wrong: I can use CORS to my local server with Post normally - Access-Control-Allow-Headers does accept wildcards. It's also wrong, wildcard works for me (I tested only with Chrome)
我发现了类似的问题和一些误导性的回答: - 服务器线程说这是 2 年的 chrome 错误:Access-Control-Allow-Headers 与 localhost 不匹配。这是错误的:我可以通过 Post 正常使用 CORS 到我的本地服务器 - Access-Control-Allow-Headers 确实接受通配符。这也是错误的,通配符对我有用(我只用 Chrome 测试过)
This take me half day to figure out the issue.
这花了我半天时间来弄清楚这个问题。
Happy coding
快乐编码
回答by Karmo Rosental
I'm using self-signed certificate on my api server and that seems to be the issue. I found that if I start Google Chrome with --disable-web-security
option, then CORS with request headers is working. Without --disable-web-security
I can send CORS requests to self-signed api server but can't add any headers (except Content-Type).
我在我的 api 服务器上使用自签名证书,这似乎是问题所在。我发现如果我使用--disable-web-security
选项启动 Google Chrome ,那么带有请求标头的 CORS 就可以正常工作。没有--disable-web-security
我可以将 CORS 请求发送到自签名 api 服务器,但不能添加任何标头(Content-Type 除外)。
回答by Varunkumar Nagarajan
Server side: The server should set the header "Access-Control-Allow-Credentials" and also set the allowed headers in "Access-Control-Allow-Headers".
服务器端:服务器应设置标头“Access-Control-Allow-Credentials”,并在“Access-Control-Allow-Headers”中设置允许的标头。
Client side: You can set xhrFields in $.ajax() instead of explicitly passing Auth header.
客户端:您可以在 $.ajax() 中设置 xhrFields,而不是显式传递 Auth 标头。
xhrFields: {
withCredentials: true
}
More details here.
更多细节在这里。