web-dev-qa-db-ja.com

このCORSリクエストがFirefoxでのみ失敗するのはなぜですか?

私は資格情報とプリフライトリクエストでCORSを実装しています。プリフライトリクエストがFirefox 30で一貫して失敗するのに、Safari(7.0.2)およびChrome 35で動作する理由は少し分かりません。この問題は異なると思いますfrom 認証されたCORSリクエストのプリフライトOPTIONSリクエストはChromeで機能しますが、Firefoxでは機能しません。 "401でなく、ブラウザからCORS固有のメッセージを受け取るためです。クライアント:

「クロスオリジンリクエストのブロック:同じオリジンポリシーは、 http://myurl.dev.com のリモートリソースの読み取りを許可しません。これは、リソースを同じドメインに移動するか、CORSを有効にすることで修正できます。 」

ソースコードを表示せずに、私がやっていることは次のとおりです。

サーバー上

OPTIONS応答のヘッダー:

  • Access-Control-Allow-Origin:[[ここからリクエストのコピー元]]
  • Access-Control-Allow-Methods:「POST GET OPTIONS」
  • Access-Control-Allow-Headers: "X-Requested-With"
  • Access-Control-Allow-Credentials: "true"

POST応答のヘッダー:

  • Access-Control-Allow-Origin:[[ここからリクエストのコピー元]]
  • Access-Control-Allow-Credentials: "true"

ブラウザクライアント:

jQuery.ajax({
  url: requestUrl,
  type: 'POST',
  data: getData(),
  xhrFields: {
    withCredentials: true
  }
});

仕様に従って、これにより、応答にCORSヘッダーを含める必要があるOPTIONSプリフライトリクエストがトリガーされます。私はW3Cの仕様を何度も読みましたが、そのプリフライトレスポンスで何が間違っているのかを特定できません。

22
rq_

Firefoxがここで準拠している唯一のブラウザであることに注意してください。 https://fetch.spec.whatwg.org/#cors-preflight-fetch ごとにAccess-Control-Allow-Methodsの解析が失敗した場合、ネットワークエラーを返す必要があります。そして、ヘッダー値のABNFごとに、間違いなくコンマ区切り値です。

10
Anne

Cookieが設定されたCORS(Cross Origin Resource Sharing)要求を送信すると、Firefoxは必要な応答ヘッダーを送信しないことに気付きました。

解決策:

以下のソリューションは、OPTIONSリクエストにのみヘッダーを追加し、example.comからのリクエストのみを受け入れます。他の要求メソッドと予想されるホストの実装を変更できます。

JSコード

var xmlhttp = new XMLHttpRequest();
xmlhttp.withCredentials = true;

xmlhttp.onreadystatechange = function () {
    if (xmlhttp.readyState == XMLHttpRequest.DONE) {
        if (xmlhttp.status == 200) {
            success_callback(xmlhttp.responseText);
        } else {
            error_callback(xmlhttp.statusText);
        }
    }
};
xmlhttp.open("DELETE", url);
xmlhttp.send(null);

DELETEリクエストを送信すると、ブラウザはOPTIONSのプリフライトリクエストを送信します。これは、応答ヘッダーにAccess-Control-Allow-Methodsを期待します。このヘッダー値に基づいて、実際のDELETE要求が送信されます。 Firefoxでは、DELETEリクエストを送信すると、プリフライトリクエストのレスポンスヘッダーに予期されるヘッダーがないため、実際のDELETEリクエストを送信できません。

この問題を解決するには、以下のNGINXサーバー設定を使用します。

NGINX CODE

#handle CORS requests by adding required headers
if ($http_Origin ~* .example.com) {
    set $cors "CORS-${request_method}";
}

if ($cors = "CORS-OPTIONS") {
    add_header 'Access-Control-Allow-Credentials' 'true';
    add_header 'Access-Control-Allow-Headers' 'Content-Type';
    add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, DELETE';
    add_header 'Access-Control-Allow-Origin' $http_Origin;
}

CORSをよく読んでください: https://www.html5rocks.com/en/tutorials/cors/

0
Akshay Goyal