スポンサーリンク
Fetch APIって何ぞや?
Fetch API は JavaScirpt標準仕様で、非同期 HTTPリクエスト送信するための APIです。
これまでは、標準 APIで非同期通信を実装する場合は、XMLHttpRequest(XHR)を使って見辛いコードで書くか、サードパーティー制の、jQueryや axiosなどのライブラリを使用する方法があり、どちらかと言えば後者の作りが主流でした。
そして満を持して登場したのが「Fetch API」です!!
Fetch APIは、XMLHttpRequest(XHR)に代わる標準 API として提供され、XHRと同等の機能を提供しながら、jQueryや axiosのように、シンプルモダンに非同期(Ajax)処理が書ける APIです。
Fetch APIのブラウザ対応状況
2021年6月現在では、IE以外の主要なモダンブラウザが Fetch APIに対応しており、現に多くのWEB開発プロジェクトでは Fetch APIの採用が始まっています。
では、Fetch APIの使い方を学んでいきましょう。
GETリクエストをFetch APIで送る
最初はシンプルに GETリクエストを送信する方法を紹介します。
次のコードは、Fetch APIの fetch
関数でGETリクエストを送信し、結果(レスポンス)をJSONで取得する例です。
const response = await fetch("https://httpbin.org/delay/2");
const data = await response.json()
console.log(data)
このように、Fetch APIでは基本的に fetch
関数を使用して非同期リクエストを送信します。
fetch
関数の戻り値はPromiss
であるため、async/await
パターンを使って非同期処理をシンプルに記述できるのが特徴です。
Promise.thenパターンで書く場合
fetch
の戻り値はPromiss
であるため、当然ながら従来の Promise.then
パターンの書き方もできます。上のサンプルコードを、 Promise.then
の書き方に変えたのが次のコードです。
fetch('https://httpbin.org/delay/2')
.then((response) => response.json())
.then((data) => console.log(data));
レスポンスを受け取る
fetch
関数から取得したレスポンスから JSON/TEXTなどのデータ本文を取得には、取得したいデータ形式に合わせて次の関数を呼び出します。
const response = await fetch("https://example.com");
const buff = await response.arrayBuffer(); // バイナリデータバッファで取得
const blob = await response.blob() // Blobで取得
const form = await response.formData() // フォームデータで取得
const json = await response.json() // JSONで取得
const text = await response.text(); // テキストデータで取得
スポンサーリンク
POSTリクエストを送る
次は、非同期の POSTリクエストを Fetch APIで送る方法を見てみます。
fetch
関数は、特に指定しないとデフォルトでGET
リクエストを送信するため、POST
リクエストを送信する場合は、引数のオプションに method: "POST"
を指定します。
const response = await fetch("http://xxx.com/post", {
method: "POST", // GET POST PUT DELETEなど
body: bodyData // リクエスト本文をセット
});
フォーム(multipart/form-data)形式でPOSTする
フォーム形式の multipart/form-data
でPOSTする場合は、FormData
クラスにデータを格納して送信します。
var form = new FormData()
form.append('nama', 'Yamada')
form.append('address', 'Tokyo')
const response = await fetch("http://xxx.com/post", {
method: "POST", // GET POST PUT DELETEなど
body: form // リクエスト本文にフォームデータを設定
});
console.log(await response.json())
application/x-www-form-urlencoded形式でPOSTする
URLエンコードありのフォーム形式の application/x-www-form-urlencoded
でPOSTする場合は、URLSearchParams
クラスを使います。
var params = new URLSearchParams()
params.append('id', 123)
params.append('name', 'Yamada Tarou')
const response = await fetch("http://xxx.com/post", {
method: "POST",
body: form // リクエスト本文にURLSearchParamsを設定
});
console.log(await response.json())
JSON形式(application/json)でPOSTする
JSON形式のデータを POSTする場合は、body
に JSON.stringify
などで文字列にした JSON形式のデータを設定します。
また、このままでは Content-Type
がプレーンテキストの text/plain
として判別されてしまうため、合わせて 'Content-Type': 'application/json'
ヘッダを設定します。
var data = {
name: "Yamada",
age: 20
};
const response = await fetch("http://xxx.com/post", {
method: "POST",
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data) // リクエスト本文に文字列化したJSON形式のデータを設定
});
console.log(await response.json())
Fetch APIで HTTPのステータスコードを取得する
リクエストが成功したかを確認するには、Response
オブジェクトのok
プロパティで取得できます。
ok
プロパティは、HTTPステータスコードが200番台(200~299)であればtrue
を返し、それ以外の400や500番台のHTTPステータスコードであればfalse
を返します。
const response = await fetch("http://xxx.com/get");
if (response.ok) {
console.log("正常です");
}
また、HTTPステータスコードを取得したい場合は、Response
オブジェクトのstatus
プロパティから取得できます。
const response = await fetch("http://xxx.com/get");
console.log("HTTPステータスは、" + response.status + "です。");
ファイルをダウンロードする
ファイルのダウンロードをする場合は、fetch
で取得したレスポンスの blob()
関数でファイルのバイナリが取得できるため、それを data URLに変換し a
タグにセットすればよい。
const response = await fetch("http://xxx.com/download")
const blob = await response.blob()
const a = document.createElement('a')
a.href = URL.createObjectURL(blob)
a.download = `sample.png`
a.click()
ファイルをアップロードする
Fetch APIで画像などのファイルをアップロードする場合は、以下のように書きます。基本的に他の POSTと書き方は変わりません。
var form = new FormData()
var file = document.getElementById("file")
form.append('file', file.files[0])
const response = await fetch("http://xxx.com/upload", {
method: "POST",
body: form // リクエスト本文(ファイル)をセット
});
上のコードを実行する場合は、HTMLに、次のようにフィアル選択用の`INPUT`要素が配置しておく必要があります。
<input id="file" type="file"/>
HTTPリクエスト・ヘッダを付ける
ヘッダを付けてHTTPリクエストを送信する場合は、fetch
関数のパラメータにheader
を設定します。
const response = await fetch("http://xxx.com/post", {
headers: new Headers({
"Content-type": "application/octet-stream"
})
});
スポンサーリンク
認証情報を含むCookieの送信設定
APIによっては、認証情報を含む「Cookie」の送信が必要なことがあります。
Fetch APIでは、サイトのログイン情報などを含む「Cookie」の送信範囲を、credentials
オプションで指定します。
omit
:同一オリジン(自サイトのドメイン)のリクエストの場合でも送信しません。
same-origin
:クロスオリジン(外部のドメイン)には送信しません。
include
:クロスオリジン(外部のドメイン)でも常に送信います。
デフォルト値はsame-origin
です。
// ↓ credentials オプションの使用例
const response = await fetch("http://xxx.com/get", {
credentials: 'include'
});
Basic認証を行う
Basic認証を行う場合は、ヘッダに認証情報をBase64エンコードした認証情報を付けてリクエストを送信します。
const response = await fetch("http://xxx.com/post", {
headers: new Headers({
Authorization: "Basic " + btoa("user" + ":" + "pass")
})
});
thenパターンでFetch APIを使う
ここまでは、async/await
パターンでFetch APIを使用する方法を紹介してきましたが、then ~ catchパターンでFetch API
を使う方法も最後に紹介します。
Fetch APIは、fetch
関数でリクエストを送信する所と、response.json()
,response.text()
などのレスポンス本文を取得する関数で、それぞれPromiss
が返ってくるため、then
を2段階で構える必要があります。
fetch("http://xxx.com/get")
.then((response) => response.json())
.then((json) => console.log(json))
.catch((error) => console.log(error));
IEなどの未対応のブラウザはPolyfillで対応
Fetch APIは、IE(internet explorer)非対応です。
すでに IEはサポートが終了しており、使っている人は限られ無視していいレベルかとは思いますが、IE上で動くWeb アプリでも Fetch APIを使いたい場合は、Polyfill が使用できます。
Fetch APIの Polyfillは CDNJSで公開されています。Polyfillを使用する場合は、先にPolyfill用のスクリプトを読込み、次に Fetch API用の関数を模倣したスクリプトの読み込みを行います。
<script src="https://cdnjs.cloudflare.com/ajax/libs/promise-polyfill/8.2.0/polyfill.min.js" integrity="sha512-YK+bAjUuYdjPksbGQIIIsUn5hgYFsc+nXgx21Wwby9Mv+rJd8WZH2FRe1RdlTjFu1vxlGia9/RqmUMcZtX+BrA==" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fetch/3.4.1/fetch.min.js" integrity="sha512-+iXlQLHKQZYoFQZfyWkUuJB6X7aZA2+FvAB5PyiYzxRKbgmSLp6vzwXjTlqdvKV5OJS09HHN4lIekb5OOCKhQw==" crossorigin="anonymous"></script>
さいごに
Fetch APIの使い方について紹介してきました。
少し前までは、jQuery
やaxios
などの外部ライブラリでAJAX処理をするのが一般的でしたが、Fetch APIの登場によって、標準の関数で容易にAJAX処理ができるようになりました。
今後は、Fetch APIが主流になっていきそうなので、注目していきましょう。
0 件のコメント:
コメントを投稿