49

CORS Specによると 、GET および POST リクエストは透過的に 302 リダイレクトに従う必要があるようです。しかし、Chrome がリクエストをキャンセルしています。

リクエストを行うJSは次のとおりです。

var r = new XMLHttpRequest();
r.open('GET', 'https://dev.mysite.com/rest', true);
r.send();

これが起こるべきことです:

  1. クライアント: /rest への XHR POST リクエスト
  2. サーバー: /rest/ への HTTP 302 リダイレクトで応答します
  3. クライアント: そのリダイレクトに従ってください

ただし、ステップ 2 の後、Chrome はリクエストをキャンセルします。HTTP 302 がなければ、リクエストは完全に機能します。これを確認しました。

リクエストが実行されると、Chrome のネットワーク パネルに XHR が 1 つだけ表示されます。これは、レスポンス ヘッダーやレスポンス ボディのないキャンセルされた POST リクエストです。

Chrome の net-internals ツールでデバッグすると、サーバーから応答が送信され、その後、要求がキャンセルされたことがわかりました。リクエストの出力は次のとおりです。

79295: URL_REQUEST
https://dev.mysite.com/rest
Start Time: 2013-08-30 12:41:11.637

t=1377880871637 [st=    0] +REQUEST_ALIVE  [dt=13455]
t=1377880871638 [st=    1]    URL_REQUEST_BLOCKED_ON_DELEGATE  [dt=1]
                              --> delegate = "extension Adblock Plus"
t=1377880871639 [st=    2]   +URL_REQUEST_START_JOB  [dt=13453]
                              --> load_flags = 143540480 (DO_NOT_SAVE_COOKIES | DO_NOT_SEND_AUTH_DATA | DO_NOT_SEND_COOKIES | ENABLE_LOAD_TIMING | MAYBE_USER_GESTURE | REPORT_RAW_HEADERS | VERIFY_EV_CERT)
                              --> method = "POST"
                              --> priority = 2
                              --> upload_id = "0"
                              --> url = "https://dev.mysite.com/rest"
t=1377880871639 [st=    2]      HTTP_CACHE_GET_BACKEND  [dt=0]
t=1377880871639 [st=    2]     +HTTP_STREAM_REQUEST  [dt=7]
t=1377880871646 [st=    9]        HTTP_STREAM_REQUEST_BOUND_TO_JOB
                                  --> source_dependency = 79296 (HTTP_STREAM_JOB)
t=1377880871646 [st=    9]     -HTTP_STREAM_REQUEST
t=1377880871646 [st=    9]     +HTTP_TRANSACTION_SEND_REQUEST  [dt=0]
t=1377880871646 [st=    9]        HTTP_TRANSACTION_SEND_REQUEST_HEADERS
                                  --> GET /facultyportfolio-rest HTTP/1.1
                                      Host: dev.liberty.edu
                                      Connection: keep-alive
                                      Content-Length: 46
                                      Origin: http://localhost:8080
                                      User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.62 Safari/537.36
                                      Content-Type: application/json; charset=UTF-8
                                      Accept: */*
                                      Referer: http://localhost:8080/ajaxtest.html
                                      Accept-Encoding: gzip,deflate,sdch
                                      Accept-Language: en-US,en;q=0.8
t=1377880871646 [st=    9]        HTTP_TRANSACTION_SEND_REQUEST_BODY
                                  --> did_merge = true
                                  --> is_chunked = false
                                  --> length = 46
t=1377880871646 [st=    9]     -HTTP_TRANSACTION_SEND_REQUEST
t=1377880871646 [st=    9]     +HTTP_TRANSACTION_READ_HEADERS  [dt=1001]
t=1377880871646 [st=    9]        HTTP_STREAM_PARSER_READ_HEADERS  [dt=1000]
t=1377880872646 [st= 1009]        HTTP_TRANSACTION_READ_RESPONSE_HEADERS
                                  --> HTTP/1.1 302 Found
                                      Date: Fri, 30 Aug 2013 16:41:11 GMT
                                      Server: Apache/2
                                      Access-Control-Allow-Origin: http://localhost:8080
                                      Access-Control-Allow-Credentials: true
                                      Location: https://dev.mysite.com/rest/
                                      Content-Language: en-US
                                      Vary: Accept-Encoding,User-Agent
                                      Content-Encoding: gzip
                                      Content-Length: 20
                                      Connection: close
                                      Content-Type: text/plain; charset=UTF-8
t=1377880872647 [st= 1010]     -HTTP_TRANSACTION_READ_HEADERS
t=1377880872647 [st= 1010]     +URL_REQUEST_BLOCKED_ON_DELEGATE  [dt=12445]
t=1377880885091 [st=13454]        CANCELLED
t=1377880885092 [st=13455]   -URL_REQUEST_START_JOB
                              --> net_error = -3 (ERR_ABORTED)
t=1377880885092 [st=13455] -REQUEST_ALIVE

最後に、「URL_REQUEST_BLOCKED_ON_DELEGATE」のため「キャンセル」と表示されます。それが何を意味するのかわかりません。ただし、HTTP 302 リダイレクトがなければ、エラーは発生しません。

Chrome がこのリクエストをキャンセルする原因を知っている人はいますか?

4

4 に答える 4

30

ここでの回答はまちまちで、CORS のリダイレクトの問題を解決する可能性のあるコードなどの特定の設定を示唆していますが、CORS 仕様では、そのような CORS リダイレクトがいつ失敗/パスするかを明確に指定しています。

  1. リダイレクトされたリソースへのリクエストがプリフライト チェックを必要としない場合 (たとえば、カスタム ヘッダーのない単純な CORS リクエスト)、3XX リダイレクトを許可します。https://www.w3.org/TR/cors/#simple-cross-origin-request-0を参照してください

手動リダイレクト フラグが設定されておらず、応答の HTTP ステータス コードが 301、302、303、307、または 308 の場合は、リダイレクト手順を適用します。

  1. リダイレクトされたリソースへのリクエストでプリフライト チェックが必要な場合は、3XX リダイレクトを許可しないでください。https://www.w3.org/TR/cors/#cross-origin-request-with-preflight-0を参照してください

応答の HTTP ステータス コードが 301、302、303、307、または 308 の場合 キャッシュとネットワーク エラーの手順を適用します。

github リポジトリでさまざまな CORS シナリオを調査しました: https://github.com/monmohan/cors-experiment

リダイレクトの失敗に関するこの特定の問題は、https ://github.com/monmohan/cors-experiment/tree/master/issue のバンドルによって分離して簡単に再現することもできます。

于 2016-08-07T02:40:24.023 に答える
2

また、Chrome が CORS リクエストのリダイレクトに従っていないという問題もありました。私にとっての問題は、私が使用している JS フレームワーク (Sencha Touch) がリクエスト ヘッダーを追加することでした: X-Requested-With: "XMLHttpRequest"

これを削除するとすぐに (Sencha Touch で Ext.Ajax.setUseDefaultXhrHeader(false); を呼び出して)、魔法のように機能しました。

理由はわかりませんが、この情報が誰かの役に立てば幸いです。

于 2013-09-09T13:42:37.953 に答える