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).
jQuery script:
$(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:
> 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?
Maybe your https server has an untrusted certificate. If so, try accessing to the URL with your browser first, and accepting the untrusted connection.
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:
- https://code.google.com/p/chromium/issues/detail?id=96007
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/):
- 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 desktop an 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”
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).
Worth mentioning that there's ANOTHER case that yields absolutely identically looking results :
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 ..)
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/');