テスト姉妹がバグについて言及しましたが、なぜオプション要求があるのですか?
1 仕事を終える前の沈黙
仕事を終えようとしていたところ、テストのお姉さんが私に別の質問をしてくれましたbug
。ほら、これは一度やったのですが、network
なぜ 2 つのリクエストがあるのですか?
私はびっくりしました。「ありえない! 私のコードはバックエンド インターフェイスを 1 回呼び出しているのに、リクエストが 2 回あるわけがない!」。彼女のスクリーンショットを開いて見てください: 複数のoptions
リクエスト。
私は冷静に説明しました。「心配しないでください。これはデフォルトでブラウザによって送信されるプリフライト リクエストです。」
しかし、テストのお姉さんは依然として非常に粘り強いようです。「では、これは絶対に不可能です。1 回リクエストしたのに、なぜ 2 回リクエストする必要があるのですか。これにより、サーバーへの負荷が増大するのではありませんか?」
「MD、あなたはとても頑固なので、私は仕事を休まないで、追加の1時間であなたに説明します!」
HTTP リクエストには次の 2 種類があります。
- 簡単なリクエスト
- 単純ではないリクエスト
2つの簡単なリクエスト
2.1 条件
-
リクエスト方法:
HEAD
、GET
、POST
-
ヘッダーには、次のリクエスト ヘッダー フィールドのみを含めることができます。
-
Accept
-
Accept-Language
-
Content-Language
-
Content-Type で参照されるメディア タイプの値は、次の 3 つのいずれかに限定されます。
text/plain
multipart/form-data
application/x-www-form-urlencoded
-
2.2 ブラウザの処理方法の違い
単純なリクエスト。リクエストがクロスドメインの場合、ブラウザはリクエストの送信を許可します。ブラウザはcors
リクエストを送信し、それを運びますorigin
。現時点では、サーバーが何を返しても、ブラウザはその戻り値をインターセプトし、response
それが返されたheader
かどうかを確認しますAccess-Control-Allow-Origin
。
- 通常、このヘッダー情報の値は request の値です
Origin
。つまり、このソースからのリクエストは、リソースが共有されており、リソースを取得できることを示すことが許可されます。 - ヘッダー情報の値が「*」(どの送信元からのリクエストも許可することを示す)の場合
Origin
、セキュリティ上のリスクがあるため注意が必要です。 - このようなヘッダー情報がない場合は、サーバー上でリソース共有が有効になっていないことを意味し、ブラウザはリクエストの終了に失敗したものとみなし、エラーを報告します。
3 単純ではないリクエスト
単純なリクエストの条件が満たされない限り、それは非単純なリクエストです。
非単純なcors
リクエストを発行するには、ブラウザはhttp
クエリ リクエスト (プリフライト リクエスト)を実行しますoptions
。options
リクエストは単純なリクエストとして処理されます。
なぜoptions
リクエストをするのでしょうか?
サーバーがクロスドメインリクエストをサポートしているかどうかを確認し、実際のリクエストのセキュリティを確認してください。プリフライト リクエストは、クライアントのセキュリティを保護し、信頼できない Web サイトがユーザーのブラウザを使用して悪意のあるリクエストを他の Web サイトに送信するのを防ぐことです。キャリー フィールドに加えてorigin
、プリフライト リクエスト ヘッダーには 2 つの特別なフィールドも含まれています。
-
Access-Control-Request-Method
:実際のリクエストに使用されたHTTP
メソッドをサーバーに通知します -
Access-Control-Request-Headers
: 実際のリクエストによって運ばれるカスタムヘッダーフィールドをサーバーに通知します。
のように:
OPTIONS /resources/post-here/ HTTP/1.1
Host: bar.other
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Connection: keep-alive
Origin: http://foo.example
Access-Control-Request-Method: POST
Access-Control-Request-Headers: X-PINGOTHER, Content-Type
上記のメッセージからわかるように、OPTIONS
ブラウザはリクエストを使用して、上で使用したリクエスト パラメータに従ってリクエストを送信する必要があるかどうかを判断します。これにより、サーバーは実際のリクエスト パラメータを使用してリクエストを送信してもよいかどうかを応答できます。
-実際のリクエストがメソッドAccess-Control-Request-Method
を使用して行われることをサーバーに伝えます。POST
Access-Control-Request-Headers
X-PINGOTHER
実際のリクエストには 2 つのカスタム リクエスト ヘッダー フィールド (と )が含まれることをサーバーに通知しますContent-Type
。これに基づいて、サーバーは実際のリクエストが許可されるかどうかを決定します。
プリフライトリクエストはいつトリガーされますか?
- クロスドメインリクエストを送信する場合、リクエストヘッダーにはカスタムヘッダー(カスタムヘッダー)などのいくつかの非単純なリクエストヘッダー情報が含まれます。
- クロスドメインリクエストを送信する場合、PUT、DELETE、CONNECT、OPTIONS、TRACE、PATCH などのリクエストメソッドが使用されます。
「お姉さん、分かりましたか?だから、これはバグじゃないので、早く消してください!」
お姉さんはハッキリとした表情を漏らした、ね?
4件
今度はテストのお姉さんがついにバグを怪しげに閉じてくれました。
5 この世にテスト妹がいないなら
もしやと言いました!テスト担当者はこう言いました。「あなたの言ったことは理解できません。気にしません。とにかく、私が今確認したいのは、ブラウザーにネットワーク リクエストが 1 つだけあるということです。それはあなた自身で理解してください。私は帰ります」ここのバグは自分で対処してください。
のように!セキュリティを確保するために、ブラウザのメーカーはクロスドメインを禁止していますが、最終的にはプログラマーがすべての最適化のコストを負担します。