fetchとは
fetchとは、簡単に言うとHTTPリクエストを送る関数です。
引数にリクエストを送るURLを入れると、リクエストが送信できます。
fetch('https://example.com')
fetch関数はプロミスを返します。
そのためawaitと組み合わせて使い、リクエストが完了するまで待機することが多いです。
const response = await fetch('https://example.com')
なお、このプロミスは、リクエストが正常に完了したらResponseオブジェクトで履行されます。
そのためこのコードでのresponseにはResponseオブジェクトが入ります。
例
Responseオブジェクトはいくつかのメソッドとプロパティを持っています。
詳細はResponseで解説しますが、ここではtextの使用例を紹介します。
以下はtextメソッドを使ってレスポンスボディを文字列にし、それをログに出力する例です。
const response = await fetch('https://example.com')
const text = await response.text()
console.log(text) // レスポンスボディを文字列にしたものが出力される
ブラウザから実行した場合、リクエストがCORSポリシーに違反しているという理由でリクエストが拒否されることがあります。
その場合はNode.jsなどのサーバーサイドから実行するか、https://example.comのコンソールから実行してみてください。
Request
RequestオブジェクトはHTTPリクエストを示すオブジェクトです。
これはfetchの引数に入れたりできます。
const request = new Request('https://example.com')
const response = await fetch(request)
Requestは第一引数にURL1を、第二引数にオプションを取ります。
new Request('ここにURL', {
// ここにオプション
})
fetchの引数はRequestのコンストラクタの引数と同じです。
そのためRequestで紹介する内容はそのままfetchの引数に流用できます。
options
第二引数のoptionsはオブジェクトになっていて、いくつかのオプションを入れることができます。
全てのオプションはこちらから見れます。
ここでは、よく使いそうなオプションを挙げておきます。
headers
リクエストヘッダを示すオブジェクトが入ります。
これはヘッダー名がキー、ヘッダーの値が値という形式です。
よく使うヘッダーの一つに、'Content-Type': 'application/json'があります。
これは例えば、POSTリクエストのボディがJSON形式であることを示すのに使います。
await fetch('https://example.com', {
method: 'POST',
// ヘッダーを指定
headers: {
// bodyがJSON形式であることを示す
'Content-Type': 'application/json'
},
// リクエストボディを入れる
body: JSON.stringify({ message: 'Hello World!' })
})
また、ここにはHeaderオブジェクトを入れることもできます。
body
リクエストボディを入れられるオプションです。
これは以下の形式に対応しています。
- 文字列(
string) BlobFormData- etc...
例えば、先ほどのContent-TypeヘッダーやJSON.stringifyと組み合わせて、JSON形式のリクエストを送ることができます。
// リクエストボディに入れるオブジェクト
const bodyObj = {
username: 'nanasi',
post: {
title: 'Hello World!',
body: 'ここに本文'
}
}
await fetch('https://example.com', {
method: 'POST',
headers: {
// bodyがJSON形式であることを示す
'Content-Type': 'application/json'
},
body: JSON.stringify(bodyObj) // JSON形式の文字列に変換する
})
GETやHEADなど、一部のリクエストメソッドではbodyオプションを指定できません。
signal
リクエストを途中で中断させるのに使えます。
HTTPリクエストは実行にそれなりの時間やコストがかかることも多いです。
そのため途中で不要になったリクエストを中断し、リソースの節約を試みることができます。
これにはAbortControllerのsignalを使うことが多いと思います。
// コントローラーを作成
const contorller = new AbortController()
// 通常のリクエスト
const promise = fetch('https://exampel.com', {
signal: controller.signal // シグナルを設定
})
// リクエストを中断する
controller.abort()
// fetchのプロミスがAbortErrorで拒否される
詳細はこちらの記事が参考になると思います。
Response
リクエストのレスポンスを示すオブジェクトです。
これはコンストラクタから生成するというより、fetchなどのAPIから返されるものを使うことが多いと思います。
// Responseオブジェクトが入る
const response = await fetch('https://example.com')
response.ok // true
await response.text() // レスポンスボディの文字列
メソッド / プロパティ
ok
リクエストが成功したかを示すプロパティで、値はbooleanです。
const response = await fetch('https://example.com')
response.ok // true
これはステータスコード(status)が200 ~ 299ならtrue、それ以外(404や500)ならfalseになります。
// 存在しないページにリクエストを送る
const response = await fetch('https://example.com/not-found')
response.ok // false
status
リクエストのHTTPステータスコードを示すプロパティです。
ステータスコードには例えば200(正常に完了)や404(ページが見つからない)、500(サーバーエラー)などが挙げられます。
// 存在するページにリクエストを送る
const response = await fetch('https://example.com')
response.ok // true
response.status // 200
// 存在しないページにリクエストを送る
const response = await fetch('https://example.com/not-found')
response.ok // false
response.status // 404
ステータスコード一覧はこのサイトがわかりやすかったです。
text
レスポンスボディを文字列にして返すメソッドです。
このメソッドは文字列で履行されるプロミスを返します。
そのため、thenやawaitとセットで使うことが多いです。
const response = await fetch('https://example.com')
// リクエストが正常に完了したかチェック
if (!response.ok) {
throw new Error(`リクエストが正常に完了しませんでした`)
}
// レスポンスボディを取得
const body = await response.text()
console.log(body) // レスポンスボディが出力される
なお、thenを使ってresponse変数を省略することもできます。
const body = await fetch('https://example.com')
.then(res => res.text()) // thenを使って一気に処理する
console.log(body) // レスポンスボディが出力される
response.okなどでのチェックをすっ飛ばして直接レスポンスボディを使いたいときは、この方法を使うと簡潔に書けます。
json
レスポンスボディがJSON形式の場合、jsonメソッドを使うことでJavaScriptのオブジェクトとしてボディを取得することができます。
const body = await fetch('https://example.com') // 何かJSONを返すAPI
.then(res => res.json()) // jsonメソッドを使用
console.log(body) // { なんらかのオブジェクト }
これはres.textで取得したテキストをJSON.parseを使ってオブジェクトにした場合と同じように動きます。
// JSON.parseを使う場合
const body = await fetch('https://example.com')
.then(res => res.text())
.then(text => JSON.parse(text))
// textを使う場合
const body = await fetch('https://example.com')
.then(res => res.json())
なお、レスポンスボディがJSONでなかった場合、このメソッドはSyntaxErrorを投げます。
レスポンスの形式には注意してください。