恥ずかしながらFetchAPIたるものがあるのを知らなかったので、ざっくり試してみた。
Fetch API
Service Workersでも使えて、プレーンなJavaScriptのXMLHttpRequestより強力で柔軟な操作ができるそうです。
GET
fetch(api_url, {method: 'GET'}) .then((res) => { // resはResponseオブジェクト console.log( res ); // 返されたBodyをjsonにしてPromise.resolve()する return res.json(); }) .then((data) => { // api_url から返されたデータ(json) // 実際にデータを加工したり色々する console.log( data ); }) .catch((err) => { console.error( err ); });
GETメソッドの場合は第二引数のmethod: 'GET'を省略することができます。
FetchAPIで最初で取得されるデータはResponseオブジェクトになっており、res.json()を実行することで返されたデータのBodyをJSON形式にしてPromise.resolve()に渡すようになっています。
JSON以外にも次のようにArrayBuffer, Blob, FormData, Stringにすることもできます。
- ArrayBuffer:
res.arrayBuffer() - Blob:
res.blob() - FromData:
res.formData() - String:
res.text()
詳しくはドキュメント: Response - Web API | MDNを参照
POST
fetch(api_url, { method: 'POST', // 送信するデータ body: post_data }) .then((res) => res.json) .then((data) => console.log( data )) .catch((err) => console.error( err ));
POSTで送信するデータはbodyオプションに指定します。
methodをPUT, DELETEにすればPUT, DELETEのリクエストも送ることが出来ます。
PUT
fetch(api_url, { method: 'PUT', body: post_data }) .then((res) => ...)
DELETE
fetch(api_url, { method: 'DELETE', }) .then((res) => ...)
クロスオリジン (クロスドメイン)の送信
クロスオリジンで通信を行いたい時はmodeオプションにcorsを指定します。
fetch(api_url, { mode: 'cros' }).then((res)...)
mode オプション
same-origin: *default 同じドメイン(same origin)のみ許可。クロスオリジンは接続エラーcors: クロスオリジンを許可。レスポンスは表示できるヘッダがCache-Control,Content-Language,Content-Type,Expires,Last-Modified,Pragmaに限定されるcorsandbasicresponses are almost identical except that a cors response restricts the headers you can view toCache-Control,Content-Language,Content-Type,Expires,Last-Modified, andPragma.no-cors: CORSヘッダーを持たないopaqueレスポンスを返すオリジン用。接続ができない場合にエラーとならずに空のレスポンスが返される。no-corsis intended to make requests to other origins that do not have CORS headers and result in anopaqueresponse, but as stated, this isn't possible in the window global scope at the moment.
no-corsについてはイマイチ理解が出来ていないのですが、クロスオリジンにリクエストを送る際はmode: 'cors'としておけば良さそうです。
詳しくは Request.mode - Web API | MDN・Response Types Introduction to fetch() | web | Google Developersを参照
クレデンシャル (認証情報: credentials)
クッキーなどのクレデンシャルを送る場合はcredentialsオプションをincludeにする
fetch(api_url, { credentials: 'include' }).then((res) => ... )
credentials オプション
omit: *default リクエストにクレデンシャル(認証情報)を含まないsame-origin: 同一オリジンの場合だけクレデンシャル(認証情報)を送るinclude: クレデンシャル(認証情報)の入ったリクエストを送る
cf. Sending_a_request_with_credentials_included | Fetch 概説 | MDN
カスタムヘッダー
クロスオリジン・クレデンシャル以外にもcache, header, redirect, referrerリクエストのヘッダーのオプションが用意されています。
e.g. JSONで指定したヘッダー情報を追加
fetch(api_url, { header: { 'Content-Type': 'application/json' } }).then((res) => ... )
Header情報はHeaderインターフェースで色々と独自な設定が可能なようです。
cf. Headers | FetchAPI 概説 | MDN
対応ブラウザとPolyfill

Can I use... Support tables for HTML5, CSS3, etc
この記事を書いた2019年1月時点では、IE11を含めたIEと、IE Mobile, Blackberry といった幾つかのモバイルブラウザで未対応をなっているようです。
Polyfillが用意されているのでこれらの非対応サポートブラウザで使用するにはこちらを利用するのが良さそうです。
Browser Support
babelしてみた
babel7で自動的にPolyfillがロードされる設定でFetchAPIが非対応ブラウザーようにバベれるか一応試してみました。
babel.config.js
const presets = [ ["@babel/preset-env", { "modules": false, "targets": ["ie > 10"], "useBuiltIns": "usage", }] ]; module.exports = { presets }
index.js
fetch('http://localhost:3000', { method: 'GET' }) .then((res) => res.json()) .then((data) => console.log(data)) .catch((err) => console.error(err));
👇$ yarn babel バベる
bandle.js
// 略 fetch('http://localhost:3000', { method: 'GET' }).then(function (res) { return res.json(); }).then(function (data) { return console.log(data); }).catch(function (err) { return console.error(err); });
PromiseのPolyfillもロードされませんでした。
babel7デフォルトの@babel/preset-envではFetchAPIはPolyfillされないようです。
FetchAPIを使っているプロジェクトで非サポートブラウザ対応をする場合は配布されているPolyfillを使用するのが良さそうです。(babelで読み込ませられるのかな?)
感想
thenを二重にしないといけないのが最初ちょっとキモかったですがjQueryを使わない場合は、生JSのXMLHttpRequestで書くよりタイプ数も少なくて済むし見通しもよいので良さそうだと思いました。(生JS...
[参考]
