Help us understand the problem. What is going on with this article?

XMLHttpRequest で リクエストメソッドが GET なのに OPTIONS リクエストが送信される

More than 1 year has passed since last update.

概要

XMLHttpRequestGET メソッド を指定しているのに OPTIONS メソッド が送信される事がありました。

XMLHttpRequest でパラメータなどは正しいのに、正しくリソースが取得できないときに役に立つかもしれません。

XMLHttpRequest の実装

GET メソッド を指定しているのに OPTIONS リクエスト が送信されるコードは下記のようなものでした。
単純に GET メソッド で指定した URL にリクエストを送信するものです。

var request = new XMLHttpRequest();
request.open('GET', 'https://hoge');

request.onload = function() {
  if (this.status >= 200 && this.status < 400) {
    var data = JSON.parse(this.response);
  }
};

request.send();

しかし、上記のようなリクエストを送ると、 GET メソッド ではなく OPTIONS メソッド が送信されます。
これは、 プリフライトリクエスト を行う条件を満たしているためです。

プリフライトリクエスト

プリフライトリクエストは OPTIONS メソッド をサーバへ送信して、本来送信したいリクエストが安全かどうかを確かめるものです。
プリフライトリクエストの流れは下記のようなものです。

  1. OPTIONS メソッド をサーバへ送信
  2. サーバは許可しているリクエストメソッドやリクエストヘッダなどをクライアントへ返信
  3. 本来のリクエストを送信

プリフライトリクエストが送られる条件

下記の条件を満たすリクエストは最初にプリフライトリクエストを行います1

  • リクエストが以下のメソッドのいずれかを使用した場合。
    • PUT
    • DELETE
    • CONNECT
    • OPTIONS
    • TRACE
    • PATCH
  • または、ユーザーエージェントによって自動的に設定されたヘッダー (たとえば Connection, User-Agent, または Fetch 仕様書で "forbidden header name" として定義されている名前のヘッダー) を除いて、 Fetch 仕様書で "CORS-safelisted request-header" として定義されている以下のヘッダー以外のヘッダーがリクエストに含まれている場合。
    • Accept
    • Accept-Language
    • Content-Language
    • Content-Type (但し、下記の要件を満たすもの)
    • DPR
    • Downlink
    • Save-Data
    • Viewport-Width
    • Width
  • または、 Content-Type ヘッダーが以下の値以外の場合。
    • application/x-www-form-urlencoded
    • multipart/form-data
    • text/plain
  • または、リクエストに使用される XMLHttpRequestUpload オブジェクトに1つ以上のイベントリスナーが登録されている場合。
  • または、 ReadableStream オブジェクトがリクエストで使用されている場合。

今回は、 Content-Type を指定していないために

Content-Type ヘッダーが以下の値以外の場合。

を満たしているので OPTIONS メソッド で送信されていました。

まとめ

仕事で GET メソッド でリソースを取得して表示するときに、サーバからエラーが帰ってきて詰まったので書きました 。
その時は、下記のことが原因でリソースを取得できませんでした。

  • サーバが OPTIONS メソッド を許可していなかった。
  • リクエスト内容が プリフライトリクエスト を送信する条件を満たしていた。

みなさんも上記のようなときは、リクエスト内容やサーバの設定を確認してみてください。

参考

オリジン間リソース共有 (CORS) - HTTP | MDN
http://takapi86.hatenablog.com/entry/2017/09/18/172846

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away