ajax 为什么 Chrome 取消 CORS OPTION 请求
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15115746/
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
Why Chrome cancel CORS OPTION request
提问by Patrik Voto?ek
in my app I'm creating AJAX request from HTTP to HTTPS. This means I need CORS. So I add some headers and params to jQuery.ajax and test it. In Firefox everythings works OK, but in Chrome not. Chrome "kill" every preflighed request (OPTIONS).
在我的应用程序中,我正在创建从 HTTP 到 HTTPS 的 AJAX 请求。这意味着我需要 CORS。因此,我向 jQuery.ajax 添加了一些标头和参数并对其进行了测试。在 Firefox 中一切正常,但在 Chrome 中不行。Chrome“杀死”每个预检请求(选项)。
jQuery script:
jQuery 脚本:
$(document).on('click', 'a.ajax', function(e) {
e.preventDefault();
$.ajax(this.href, {
type: 'GET',
dataType: 'json',
crossDomain: false,
headers: {'X-Requested-With': 'XMLHttpRequest'},
xhrFields: {
withCredentials: true
}
});
return false;
});
HTTP dump:
HTTP转储:
> OPTIONS /foo HTTP/1.1
> User-Agent: curl/7.29.0
> Host: local.bar.cz
> Accept: */*
> Access-Control-Request-Headers:accept, origin, x-requested-with
> Access-Control-Request-Method:GET
> Origin:http://local.bar.cz
>
< HTTP/1.1 204
< Server: nginx/1.2.7
< Date: Wed, 27 Feb 2013 15:06:54 GMT
< Content-Type: text/html; charset=utf-8
< Connection: keep-alive
< X-Powered-By: Nette Framework
< X-Frame-Options: SAMEORIGIN
< Access-Control-Allow-Origin: http://local.bar.cz
< Access-Control-Allow-Credentials: true
< Access-Control-Allow-Headers: accept, origin, x-requested-with
< Access-Control-Allow-Methods: OPTIONS, GET, POST, HEAD
<
any one knows why chrome kill this request?
有谁知道为什么 chrome 会终止这个请求?
回答by Abel Pastur
Maybe your https server has an untrusted certificate. If so, try accessing to the URL with your browser first, and accepting the untrusted connection.
也许您的 https 服务器有一个不受信任的证书。如果是这样,请先尝试使用浏览器访问该 URL,然后接受不受信任的连接。
回答by Akrikos
Accepting the certificate does not always solve this problem. If you use a self-signed cert, EVEN IF YOU ACCEPT IT FIRST, Chrome will still in some cases cancel your preflight OPTIONS requests. It's been this way since 2011:
接受证书并不总能解决这个问题。如果您使用自签名证书,即使您首先接受它,Chrome 在某些情况下仍会取消您的预检选项请求。自 2011 年以来一直是这样:
The workaround as noted in that page is to add the self-signed cert to your system's list of trusted certificates.
该页面中提到的解决方法是将自签名证书添加到系统的受信任证书列表中。
Instructions to do this on a Mac (modified slightly from original so that it works with OS 10.8.5 http://www.robpeck.com/2010/10/google-chrome-mac-os-x-and-self-signed-ssl-certificates/):
在 Mac 上执行此操作的说明(对原始版本稍作修改,以便它适用于 OS 10.8.5 http://www.robpeck.com/2010/10/google-chrome-mac-os-x-and-self-signed -ssl-证书/):
- In the address bar, click the little lock with the X. This will bring up a small information screen.
- Click the button that says “Certificate Information.”
- Click and drag the certificate image to
your desktopan open finder window (it doesn't appear to like dragging to desktop. - Double-click the created file. This will bring up the Keychain Access utility. Enter your password to unlock it.
- Be sure you add the certificate to the System keychain, not the login keychain. Click “Always Trust,” even though this doesn't seem to do anything.
- After it has been added, double-click it. You may have to authenticate again.
- Expand the “Trust” section. “When using this certificate,” set to “Always Trust”
- 在地址栏中,单击带有 X 的小锁。这将显示一个小信息屏幕。
- 单击显示“证书信息”的按钮。
- 单击并将证书图像拖动到
桌面打开的查找器窗口(它似乎不喜欢拖动到桌面。 - 双击创建的文件。这将打开钥匙串访问实用程序。输入您的密码以解锁它。
- 确保将证书添加到系统钥匙串,而不是登录钥匙串。单击“始终信任”,即使这似乎没有任何作用。
- 添加后,双击它。您可能需要再次进行身份验证。
- 展开“信任”部分。“使用此证书时”,设置为“始终信任”
You may need to restart Chrome for the cert to be fully trusted (the icon to change to a happy green lock in the url bar).
您可能需要重新启动 Chrome 才能完全信任该证书(网址栏中的图标变为快乐的绿色锁)。
回答by Nir
Worth mentioning that there's ANOTHER case that yields absolutely identically lookingresults :
值得一提的是,还有另一种情况会产生完全相同的结果:
If you relocate the browser to a different URL (window.location ..) while waiting for a request to return (i.e. via a promise) then the OPTIONS request will be submitted but the subsequent response (POST/GET/*) will be cancelled (naturally ..)
如果您在等待请求返回(即通过承诺)时将浏览器重新定位到不同的 URL(window.location ..),则 OPTIONS 请求将被提交,但随后的响应(POST/GET/*)将被取消(自然..)
Yes .. of course .. it's a bug if you do that .. but it might look just the same and consume hours of looking in the wrong place. consider such a code :
是的 .. 当然 .. 如果你这样做是一个错误 .. 但它可能看起来完全一样并且花费数小时寻找错误的地方。考虑这样的代码:
makeAjaxCallThatReturnsAPromise.then(
function () { // doSomething },
function () { // doSomethingElse }
);
location.replace('http://some.where/');

