Fetch API の使い方
JavaScript で通信を行う方法としては以前から XMLHttpRequest がありましたが、 あまり使い勝手の良いものではありませんでした。 最近では、XMLHttpRequest よりもっと強力で柔軟な操作が可能な API が用意されています。
Fetch API とは?
Fetch API は Promise ベースで作成されたネットワーク通信用の API です。
ブラウザに組み込まれている API ですので、何かのライブラリをインストールしたりする必要はなく、すぐに使用することができます。
Fetch API はローレベルな API で構成されているため、
jQuery の .ajax()
や Axios などの有名なライブラリと比べると、
あまり使い勝手が良いとは言えないかもしれません。
しかしながら、それゆえに無駄な処理がほとんどありません。
シンプルで軽量でコンパクトな構成になっているので、そこにメリットを感じる方も多いのではないでしょうか。
基本的な使い方
この記事ではリクエスト先の URL を全て「http://example.com/」で記述してありますので、 動作確認をしたい場合は、ご自身の環境に合わせて変更してください。
Fetch API でリクエストを送信するには fetch()
を使用します。
fetch()
の第1引数でリクエスト先の URL を指定します。
第2引数に JavaScript のオブジェクトを渡すと、リクエストの細かな設定ができます。
レスポンスは Promise で受け取ります。
詳しい使用方法は後述します。
fetch('http://example.com/') // リクエストを送る .then((response) => response.text()) // レスポンスボディをテキスト形式で取得 .then((data) => console.log(data)); // 取得した内容をコンソールに表示
async、await を使う
Fetch API のレスポンスは Promise なので、async
、await
を使用して記述することもできます。
async
、await
の使い方がわからないという方は、「async、await の使い方」を参考にしてください。
async function http() { const response = await fetch('http://example.com/'); const data = await response.text(); console.log(data); } http();
GET リクエスト
GET リクエストを使用する場合は、fetch()
の第1引数でリクエスト先の URL を指定するだけです。
リクエストメソッドはデフォルトで GET になります。
fetch('http://example.com/')
.then((response) => response.text())
.then((data) => console.log(data));
GET リクエスト(クエリーパラメーター付き)
URL のクエリーパラメーターは、パラメーターのキーと値が URL エンコードされて =
と &
で繋がれている形式です。
Fetch API には URL にクエリーパラメーターを付けてくれる機能は残念ながらありませんので、自分で付けてあげる必要があります。
JavaScript のオブジェクトからクエリーパラメータの形式に変換するには URLSearchParams
オブジェクトを使用します。
先頭の ?
を付け忘れないように注意しましょう。
const data = {
val1: 'hoge',
val2: 'fuga',
};
fetch('http://example.com/?' + new URLSearchParams(data))
.then((response) => response.text())
.then((data) => console.log(data));
http://example.com/?val1=hoge&val2=fuga
POST リクエスト
POST リクエストを使用する場合は、fetch()
の第2引数で、method
に POST
を指定します。
リクエストヘッダーの内容は headers
で、リクエストボディの内容は body
で指定できます。
POST リクエスト(テキスト形式)
リクエストヘッダーのデフォルトの Content-Type
は text/plain
です。
それ以外の Content-Type
を使用したい場合は、自分で指定する必要があります。
Content-Type
に text/html
を使用する場合
fetch('http://example.com/', { method: 'POST', headers: { 'Content-Type': 'text/html', }, body: '<h1>example</h1>', }) .then((response) => response.text()) .then((data) => console.log(data));
POST リクエスト(JSON 形式)
JSON 形式でリクエストを送信したい場合は、
リクエストヘッダーの Content-Type
に application/json
を指定します。
JavaScript のオブジェクトを JSON 形式に変換するには、JSON.stringify()
を使用します。
const data = { val1: 'hoge', val2: 'fuga', }; fetch('http://example.com/', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(data), }) .then((response) => response.text()) .then((data) => console.log(data));
Content-Type: application/json
{"val1":"hoge","val2":"fuga"}
POST リクエスト(application/x-www-form-urlencoded 形式)
application/x-www-form-urlencoded
は、通常の HTML のフォームの内容を POST で送信する際に使用されている形式です。
リクエストボディの中身は URL のクエリーパラメーターと同じ形式で、
パラメーターのキーと値が URL エンコードされて =
と &
で繋がれている形式の文字列になります。
Content-Type: application/x-www-form-urlencoded
val1=hoge&val2=fuga
この形式のリクエストを作成するには、GET リクエストでクエリーパラメーターを使用する時と同様に URLSearchParams
オブジェクトを使用します。
URLSearchParams
オブジェクトを使用すると、
自動で Content-Type
が application/x-www-form-urlencoded
に設定されます。
const data = {
val1: 'hoge',
val2: 'fuga',
};
fetch('http://example.com/', {
method: 'POST',
body: new URLSearchParams(data),
})
.then((response) => response.text())
.then((data) => console.log(data));
POST リクエスト(multipart/formdata 形式)
multipart/formdata
は、HTML のフォームでファイルを送信する際に使用されている形式です。
この形式はリクエストボディを複数の部分(その名の通りマルチパート)に分割します。
それぞれのパートには別々の項目を格納できるため、ファイルを含めた複数の項目を1度のリクエストでまとめて送ることができます。
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryTYkANbMgZavU5qqH
------WebKitFormBoundaryTYkANbMgZavU5qqH Content-Disposition: form-data; name="val1" hoge ------WebKitFormBoundaryTYkANbMgZavU5qqH Content-Disposition: form-data; name="val2" fuga ------WebKitFormBoundaryTYkANbMgZavU5qqH--
この形式のリクエストを作成するには FormData
オブジェクトを使用します。
FormData
オブジェクトを使用すると、
自動で Content-Type
が multipart/formdata
に設定されます。
パートごとの区切りである boundary
も自動で設定されます。
const formData = new FormData(); formData.append('val1', 'hoge'); formData.append('val2', 'fuga'); fetch('http://example.com/', { method: 'POST', body: formData, }) .then((response) => response.text()) .then((data) => console.log(data));
HTML のフォーム要素から設定する
FormData
オブジェクトは、HTML のフォーム要素から作成することもできます。
<form id="testForm"> <input type="text" name="val1" value="hoge"><br> <input type="text" name="val2" value="fuga"><br> <input type="file" name="testFile"><br> <button type="button">submit</button> </form>
const formElement = document.querySelector('#testForm'); const formData = new FormData(formElement); fetch('http://example.com/', { method: 'POST', body: formData, }) .then((response) => response.text()) .then((data) => console.log(data));
レスポンス
ステータスコードとステータスメッセージ
ステータスコードは .status
で取得できます。
成功したかどうか(ステータスコードが 200 ~ 299)かどうかは .ok
でも判別できます。
ステータスメッセージ(リーズンフレーズ)は、.statusText
で取得できます。
なお、HTTP/2 にはステータスコードしかなく、ステータスメッセージは無いので注意してください。
fetch('http://example.com/') .then((response) => { console.log('response.ok: ' + response.ok); console.log('response.status: ' + response.status); console.log('response.statusText: ' + response.statusText); return response.text(); }) .then((data) => console.log(data));
response.ok: true response.status: 200 response.statusText: OK
エラーの取り扱い
ステータスコードの 4XX と 5XX は、 HTTP ではエラー扱いですが、Fetch API では正常扱いになります。
つまり、Promise が resolve()
されるので、.then()
で処理する必要があるので注意してください。
Promise が reject()
されるのは、ネットワーク障害があった場合や、何かがリクエストの完了を妨げた場合のみになります。
この挙動は jQuery の .ajax()
や Axios などの有名なライブラリとは異なるので注意してください。
ステータスコードの 4XX と 5XX をエラーにしたい場合は、
.ok
でステータスを確認し、エラーを throw
すると良いでしょう。
fetch('http://example.com/') .then((response) => { if (!response.ok) { throw new Error(response.status + ' ' + response.statusText); } return response.text(); }) .then((data) => { console.log(data); }) .catch((error) => { console.error('エラーが発生しました:', error); });
レスポンスボディ(テキスト形式)
レスポンスボディの内容をテキスト形式で受け取りたい場合は、.text()
を使用します。
fetch('http://example.com/')
.then((response) => response.text())
.then((data) => console.log(data));
レスポンスボディ(JSON 形式)
レスポンスボディの内容が JSON 形式の場合、.json()
を使用すると、
その JSON をパースしてオブジェクトとして受け取ることができます。
fetch('http://example.com/')
.then((response) => response.json())
.then((data) => console.log(data));
レスポンスボディ(Blob 形式)
レスポンスボディの内容を Blob(バイナリ)形式で受け取りたい場合は、.blob()
を使用します。
fetch('http://example.com/')
.then((response) => response.blob())
.then((data) => console.log(data));