9
6

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 5 years have passed since last update.

FetchAPIの詰まりどころ

Posted at

FetchAPIの詰まりどころ

そもそもFetchAPIとは?

XMLHttpRequestの後継技術で、javascriptから非同期通信をするためのAPIです。
一昔前はjavascriptによる非同期通信というとjQuery.ajaxが主流でしたが、
普通に書いてしまうとコールバック地獄に陥りますし、今更jQuery.Defferedなど使いたくありません。

その点、fetchはPromiseをベースに作られているので、非常に簡潔に書くことができます。
例えば、特定のURLにアクセスしてJsonを取ってくる処理などはわずか2行です。

//async function内 
const resp = await fetch(url);
const json = await resp.json();

一度使い始めると最早手放せません。
某IEとかいう化石ブラウザが対応していませんが、そこはpollyfillで何とかしましょう。

癖のある動作

しかし、このfetch癖のある仕様が何か所かあります。

500や404でもRejectしない

fetchによって投げたRequestが、500エラーや404になった場合、
fetchが返すPromiseはresolve,rejectどちらになるでしょうか。
普通に考えるとrejectされそうなものですが、このfetchはそれくらいではrejectしません。
クロスオリジン制約にかかるなど、まともにリクエストすら投げられない状態がrejectであり
ステータスコードが帰ってくるのはresolveです。

ではどうやってリクエストの成功を確かめればいいのか?

とはいえHttpStatusがエラーかどうかはきちんと判別できないと困ります。
そういう場合は、Response.status または Response.okを使いましょう。
Response.statusはその名の通りHttpStatusを返し、Repsonse.okはStatusが200番台の時にtrueを返します。

const resp = await fetch(url);
if(!resp.ok){
  //エラー処理
  return;
}
const json = await resp.json();

デフォルトではCookieが乗らない

fetchAPIはデフォルトではCookieなどの認証情報が乗りません。
認証を必要とするAPIで利用する場合は、以下のようにオプションを渡してやる必要があります。

const resp = await fetch(url,{
            credentials: 'same-origin'  //同一オリジンの場合に認証情報を乗せる
        });

まとめ

  • fetchAPIは非常に便利
  • 一方でちょっと癖のある仕様も多いのできっちり確認しておくべき

参考

9
6
0

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
9
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?