246
166

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

CORS: OPTIONSリクエスト(preflight request)を避ける

Last updated at Posted at 2019-02-20

image.png

ajaxなど、ブラウザ経由でGET, POST, DELETEリクエストを投げると、実際のリクエストが走る前にOPTIONSリクエストが送信されることがあります。
一度しかリクエストを送信していなくても、実際はOPTIONSGETなど、2回リクエストが走っています。

APIによっては、OPTIONSリクエストを受け付けないため、Response to preflight request doesn't pass access control checkのようなエラーが返ってくる場合があります。このOPTIONSリクエストはCORSプリフライト(preflight requests)と呼ばれていて、これが通らないと、実際のGET, POST, DELETEなどのリクエストは送信されません。

このプリフライト・リクエストとは何なのか、OPTIONSリクエストを回避する方法はあるのか調べてみました。

プリフライト・リクエストとは

image.png
https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#Preflighted_requests

実際のリクエストを送信する前に、そのリクエストが安全かどうか、前もってOPTIONSリクエストを送信して確かめる仕様です。
これはプリフライト・リクエスト(preflight request)と呼ばれていて、ブラウザのCORS仕様の一部です。
ブラウザ経由でリクエストを送信するときにしか起こりません。
preflightという言葉からもわかるように、本番前のテスト飛行のようなイメージです。

ブラウザ上のリクエストは「単純リクエスト(simple request)」とその他のリクエストに分けられていて、単純リクエストの場合はアクセストークンなどのセンシティブな情報が含まれている可能性が低いと判断されるため、OPTIONSは送信されません。

単純リクエストとは

単純リクエストの定義、つまり、OPTIONSリクエストが飛ばない条件は以下の通りです。

  1. GET, HEAD, POSTのうちいずれか
  2. ヘッダーに含まれるのが以下のうちいずれか
  • ユーザーエージェントによって自動的に設定されたヘッダー
  • Accept
  • Accept-Language
  • Content-Language
  • Content-Type
  1. Content-Typeのヘッダーが以下のうちいずれか
  • application/x-www-form-urlencoded
  • multipart/form-data
  • text/plain
  1. リクエストに使用されるどの XMLHttpRequestUpload にもイベントリスナーが登録されていないこと。
  2. リクエストに ReadableStream オブジェクトが使用されていないこと。

ほとんどのリクエストは1 ~ 10の条件に当てはまるため、OPTIONSは飛びませんが、
REST APIのためにContent-Type: application/jsonヘッダーをつけたり、ユーザー情報の取得のためにAuthorizationヘッダーをつけたりすると、「非・単純」なリクエストと見なされて、OPTIONSリクエストが飛びます。

OPTIONSリクエストを避ける方法

リクエストが上の条件に当てはまるようにして、単純リクエストになるようにします。

GETPOSTなどでニュースのエントリを取得するなど、センシティブな情報のリクエストを含まない場合は、単純リクエストにするのはさほど問題ないかと思います。

ただし、ユーザー情報の取得のためにAuthorizationヘッダーを使っている場合など、どうしても単純リクエストにできないこともあるかと思います。
プリフライト・リクエスト(OPTIONS)はブラウザだけの仕様なので、その場合はサーバーサイドからリクエストを投げるのが吉です。

まとめ

  • OPTIONSは、実際のリクエストを投げる前のテスト飛行
  • OPTIONSが飛ばないようにするには、「単純リクエスト」の条件にあてはまるようにする
  • どうしても「単純リクエスト」にできない、かつAPIがOPTIONSに対応していない場合は、サーバーサイドからリクエストする

公式ドキュメント

246
166
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
246
166

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?