16

在我的应用程序中,我正在创建从 HTTP 到 HTTPS 的 AJAX 请求。这意味着我需要 CORS。因此,我向 jQuery.ajax 添加了一些标头和参数并对其进行了测试。在 Firefox 中一切正常,但在 Chrome 中却不行。Chrome“杀死”每个预请求的请求(选项)。

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转储:

> 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
< 

任何人都知道为什么 chrome 会终止这个请求?

4

3 回答 3

17

也许您的 https 服务器有一个不受信任的证书。如果是这样,请先尝试使用浏览器访问 URL,并接受不受信任的连接。

于 2013-03-22T08:59:49.610 回答
12

接受证书并不总能解决这个问题。如果您使用自签名证书,即使您先接受它,Chrome 在某些情况下仍会取消您的预检 OPTIONS 请求。自 2011 年以来一直如此:

该页面中提到的解决方法是将自签名证书添加到系统的受信任证书列表中。

在 Mac 上执行此操作的说明(对原始版本稍作修改,使其适用于 OS 10.8.5 http://www.robpeck.com/2010/10/google-chrome-mac-os-x-and-self-signed -ssl 证书/):

  1. 在地址栏中,单击带有 X 的小锁。这将打开一个小信息屏幕。
  2. 点击“证书信息”按钮。</li>
  3. 单击并将证书图像拖动到您的桌面打开一个查找器窗口(它似乎不喜欢拖动到桌面。
  4. 双击创建的文件。这将打开钥匙串访问实用程序。输入您的密码以解锁它。
  5. 确保将证书添加到系统钥匙串,而不是登录钥匙串。单击“始终信任”,即使这似乎没有任何作用。
  6. 添加后,双击它。您可能需要再次进行身份验证。
  7. 展开“信任”部分。“使用此证书时”设置为“始终信任”</li>

您可能需要重新启动 Chrome 才能使证书完全受信任(网址栏中的图标变为快乐的绿色锁)。

于 2013-09-27T14:03:53.577 回答
9

值得一提的是,还有另一种情况会产生完全相同的结果:

如果您在等待请求返回(即通过承诺)时将浏览器重新定位到不同的 URL(window.location ..),则将提交 OPTIONS 请求但随后的响应(POST/GET/*)将被取消(自然..)

是的..当然..如果你这样做是一个错误..但它可能看起来一样并且在错误的地方花费数小时寻找。考虑这样的代码:

makeAjaxCallThatReturnsAPromise.then(
    function () { // doSomething },
    function () { // doSomethingElse }
);
location.replace('http://some.where/');
于 2015-12-21T22:55:10.503 回答