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.set('val1', 'hoge'); formData.set('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));

