fetchのmodeについて


仕様

ここに書いてあることの和訳と実際使う時の補足。

fetchのmode

リクエストのモードを決めるオプション。

fetch(url, { mode: "cors" })

no-cors

CORS-safelisted methodsCORS-safelisted request-headersだけを使ったリクエストを送る。
成功するとopaque filtered responseを返す。

no-corsという文字通り、実質別オリジンへのリクエストとしては機能しなくなる。

CORS-safelisted methodsCORS-safelisted request-headers

https://developer.mozilla.org/ja/docs/Web/HTTP/CORS
ここの「単純リクエスト」の項目を参照。

opaque filtered response

no-corsの場合、CORSであってもエラーが出ず、下記のような虚無なレスポンスが返る。

  • type: "opaque"
  • URL list: 空
  • status: 0
  • status message: 空文字列
  • header list: 空
  • body: null

cors

CORSなリクエストを送る。
CORSのプロトコルに沿わない場合(必要なヘッダが無いなど)にはエラーとなる。

CORSなリクエストをしたいのであればこれ。

same-origin

Used to ensure requests are made to same-origin URLs. Fetch will return a network error if the request is not made to a same-origin URL.

別オリジンへのリクエストを送れないようにする。
リクエスト先が別オリジンだった場合即エラー。

navigate

ページ遷移の時に使う特別なモード。
全くわからん、ページ遷移の時にjsでfetchを発火させるってどういうユースケース?

websocket

websocketの接続を確立させるときに使う特別なモード。
仕様以外で言及されているのを見たことがないので無視して良いんじゃないかな()

modeのデフォルト値

fetchの仕様では「デフォルト値はno-corsだけど、新しい機能にno-corsを使うのは安全じゃないから推奨しないよ」と書いてあり、ChromeでもFirefoxでもSafariでもデフォルト値はcorsになります。
つまり、純粋にCORSリクエストを送る場合は何も指定しなくてOK。

結局どれ使えば良いの?

corsにしておけば良い気がしました(概ね最近のブラウザはデフォルト値がcorsなのでつまるところ指定が不要、そういう暗黙的な決定が気になる場合は明示的に指定しよう)。
同一オリジンの場合はもちろん問題なく通るし、別オリジンの場合も適切でなければエラーになります。

逆に同一オリジン以外への意図せぬアクセスをしないようにするためにsame-originとかを使う場合もあるのかな?