3秒でわかる
fetch の応答が成功扱いかどうかを表す真偽値。ステータスが 200 番台なら true になり、404 や 500 を検出できます。
もう少し詳しく
どういうものか
response.ok は、fetch が返す Response オブジェクトが持つ真偽値の性質になる。HTTP のステータスコードが 200 から 299 の範囲であれば true、それ以外は false を返す。response.status の値を毎回範囲で比べる代わりに、成功かどうかを一つの値で判定できる。
なぜ必要か
fetch は 404 や 500 が返っても失敗とみなさず、catch にも入らない。サーバーからの応答が届いた時点で通信としては成功しているためで、fetch が拒否されるのは通信そのものが成立しなかったときに限られる。この仕様を知らずに then の中でそのまま処理を続けると、エラーページの HTML を JSON として解析しようとして、原因の分かりにくい例外が出る。ok の確認は、その手前で止めるための関門になる。
具体例
async function loadUser(id) {
const res = await fetch(`/api/users/${id}`);
if (!res.ok) {
throw new Error(`取得に失敗しました status ${res.status}`);
}
return res.json();
}
loadUser(1)
.then((user) => console.log(user.name))
.catch((err) => console.error(err.message));つまずきやすいところ
if (res.ok) の確認を飛ばすのが最も多い失敗になる。Unexpected token < in JSON というエラーが出たときは、たいてい HTML のエラーページを JSON として読もうとしている。
res.ok が false の場合でも本文は読めるため、サーバーが返したエラーの詳細を取り出せる。捨てずに使うと調査が早くなる。
もう一つ、Response の本文は一度しか読めない。res.json() を呼んだあとに res.text() を呼ぶと例外になる。両方見たいときは res.clone() を先に取っておく。
リダイレクトが起きた場合、最終的な応答が 200 なら ok は true になる。意図しない転送先を掴んでいないかは res.url で確かめる。
覚え方
fetch は「届いたかどうか」までしか見ない。「中身が正しいかどうか」は ok で自分が見る。
似た用語との違い
res.status は 404 や 500 という数値そのもので、res.ok はそれが 200 番台かどうかを表す真偽値になる。原因を分けて記録したいときは status を、成功か否かだけを見たいときは ok を使う。res.statusText は補足の文言で、環境によって空になるため判定には向かない。