Posted at

FetchAPIの詰まりどころ


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で何とかしましょう。

https://github.com/github/fetch


癖のある動作

しかし、この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は非常に便利

  • 一方でちょっと癖のある仕様も多いのできっちり確認しておくべき


参考

https://developer.mozilla.org/ja/docs/Web/API/Fetch_API