我正在尝试向使用会话密钥进行授权的外部应用程序服务器发送简单的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)中不起作用。在谷歌浏览器中,它显示选项资源无法加载到网络检查器中,并且应用程序服务器没有收到任何请求。我已经尝试过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
如果我从请求中删除标头,那么我也会在谷歌浏览器中收到 401,并且在应用程序服务器上禁用授权的情况下,它能够访问资源。发送哪些标头并不重要。我能够发送的唯一标题是{"内容类型":"纯文本"}。所有其他标头名称/值在谷歌浏览器中都会出错,但在我上面提到的所有浏览器中都可以使用。
为什么谷歌浏览器不处理 CORS 请求中的标头?
谷歌浏览器中的一个错误:http://code.google.com/p/chromium/issues/detail?id=96007。
我发现应该只为"选项"请求设置访问控制-允许-标头:*。如果您将其返回用于 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: *");
}
我发现了类似的问题,但有一些误导性的回答:- 服务器线程说这是 chrome 的 2 年错误:访问控制允许标头与本地主机不匹配。错了:我可以正常使用 CORS 到我的本地服务器- 访问控制允许标头接受通配符。这也是错误的,通配符对我有用(我只用 Chrome 测试过)
这花了我半天的时间来弄清楚问题所在。
快乐编码
我在 api 服务器上使用自签名证书,这似乎是问题所在。我发现如果我使用--disable-web-security
选项启动谷歌浏览器,那么带有请求标头的 CORS 就可以工作了。如果没有--disable-web-security
我可以将 CORS 请求发送到自签名 api 服务器,但不能添加任何标头(内容类型除外)。
服务器端:服务器应设置标头"访问控制允许凭据",并在"访问控制允许标头"中设置允许的标头。
客户端:您可以在 $.ajax() 中设置 xhrFields,而不是显式传递 Auth 标头。
xhrFields: {
withCredentials: true
}
更多细节在这里。