web-dev-qa-db-ja.com

Chrome CORS OPTIONリクエストをキャンセルする理由

私のアプリでは、AJAX HTTPからHTTPSへのリクエストを作成しています。つまり、CORSが必要であることを意味します。そのため、jQuery.ajaxにヘッダーとパラメーターを追加してテストします。Firefoxでは、すべてが正常に機能します。 Chrome not。Chrome "kill" in preflighed request(OPTIONS).

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このリクエストを強制終了する理由を知っている人はいますか?

16
Patrik Votoček

多分あなたのhttpsサーバーは信頼できない証明書を持っています。その場合は、最初にブラウザーでURLにアクセスして、信頼できない接続を受け入れてみてください。

17
Abel Pastur

証明書を受け入れても、この問題が常に解決されるわけではありません。自己署名証明書を使用する場合、最初に同意した場合でも、Chromeは、場合によってはプリフライトOPTIONSリクエストをキャンセルします。2011年以来、このようになっています。

そのページに記載されている回避策は、システムの信頼できる証明書のリストに自己署名証明書を追加することです。

Macでこれを行うための手順(OS 10.8.5で動作するようにオリジナルから少し変更されました http://www.robpeck.com/2010/10/google-chrome-mac-os-x-and -self-signed-ssl-certificates / ):

  1. アドレスバーで、Xの小さな錠前をクリックします。これにより、小さな情報画面が表示されます。
  2. 「証明書情報」というボタンをクリックします。
  3. 証明書の画像をクリックしてドラッグします あなたのデスクトップ 開いているFinderウィンドウ(デスクトップにドラッグするようには見えません)。
  4. 作成したファイルをダブルクリックします。これにより、キーチェーンアクセスユーティリティが起動します。ロックを解除するにはパスワードを入力してください。
  5. 証明書は、ログインキーチェーンではなく、システムキーチェーンに追加してください。これは何もしないようですが、[常に信頼する]をクリックします。
  6. 追加されたら、ダブルクリックします。もう一度認証する必要があるかもしれません。
  7. 「信頼」セクションを展開します。 「この証明書を使用する場合」を「常に信頼する」に設定

証明書を完全に信頼するには、Chromeを再起動する必要がある場合があります(URLバーの緑色の鍵のアイコンに変更するためのアイコン))。

12
Akrikos

絶対に同一に見える結果が得られる別のケースがあることを言及する価値があります:

ブラウザが別のURL(window.location ..)に再配置され、リクエストが返されるのを(つまり、promiseを介して)待機している場合、OPTIONSリクエストは送信されますが、その後の応答(POST/GET/*)はキャンセルされます(当然..)

はい..もちろん..それを行うとバグです..しかし、同じように見え、間違った場所を探すのに何時間も費やす可能性があります。そのようなコードを検討してください:

makeAjaxCallThatReturnsAPromise.then(
    function () { // doSomething },
    function () { // doSomethingElse }
);
location.replace('http://some.where/');
8
Nir