Fetch APIの使い方まとめ!JavaScirptでGET/POSTを非同期で送信

2020年10月27日火曜日

Fetch API Javascirpt

t f B! P L

Fetch API

Fetch APIは、JavaScirptで非同期(Ajax)でHTTPリクエスト送信する APIです。

今までは、標準APIで実装する場合は、XMLHttpRequest(XHR)を使って見辛いコードで書くか、「jQuery」「axios」などの外部のライブラリを使用する方法があり、どちらかと言うと後者の作りが主流でした。

そこに登場したのが、Fetch APIです。

Fetch APIは、XMLHttpRequest(XHR)に代わるAPIとして提供され、XHRと同等の機能を提供しながら、「jQuery」「axios」のように、シンプルでモダンに非同期(Ajax)処理が書けるAPIです。

Fetch APIのブラウザ対応状況

2020年10月現在では、IE以外の主要なモダンブラウザがFetch APIに対応してきています。

では、Fetch APIの使い方を学んでいきましょう。

GETリクエストをFetch APIで送る

最初は、GETリクエストを送る方法を紹介します。
Fetch APIは、基本的にfetch関数を使用して非同期リクエストを送信します。

次のコードは、fetch関数でGETリクエストを送信し、結果(レスポンス)をJSONで取得するコードです。

const response = await fetch("http://xxx.com/get");
console.log(await response.json())

`XMLHttpRequest`を使った処理に比べて、非常に処理がシンプルにモダンに書けて、感動した方も居るのではないでしょうか?

fetch関数は、戻り値がPromissとなるため、上記のようにasync/awaitパターンで非同期処理をシンプルに記述できるのが特徴です。

レスポンスを受け取る

レスポンスは、json/text/blobなど、各コンテンツタイプに合った関数を読んで取得します。
Responseオブジェクトに定義されている関数は次のとおりです。

response.arrayBuffer(); // バイナリデータバッファで取得
response.blob()         // Blobで取得
response.formData()     // フォームデータで取得
response.json()         // JSONで取得
response.text();        // テキストデータで取得

スポンサーリンク

POSTリクエストをFetch APIで送る

次は、POSTリクエストをFetch APIで送る方法です。

fetch関数は、デフォルトでGETリスペクトになるため、POSTリクエストを送信する場合は、オプションのmethodを指定します。

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形式のデータを設定します。
文字列でbodyを指定すると、Content-Typeが自動判別されないため、あわせて'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形式の文字列を設定c
});

console.log(await response.json())

Fetch APIでリクエストが成功したか調べる

リクエストが成功したかを確認するには、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 APIでファイルをアップロードする

画像などのファイルを、Fetch APIでアップロードする場合は、以下のように書きます。

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      // リクエスト本文(ファイル)をセット
});

上のJSコードを実行する場合は、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は新しいAPIのため、IEをはじめとする古いブラウザでは使用できません。

現在、IEなどの古いブラウザは、ブラウザシェア全体の数%しか占めていないため、あきらめて無駄な労力は割かずに非対応として切り捨てるのも、現実的な1つの対応です。

どうしても、IEでFetch APIを使いたい場合は、Polyfillを使用してIEでもfetch関数等を使えるようにします。
Fetch APIのPolyfillはCDNJSで公開されています。またIEはPromiseにも非対応のため、先にPolyfillするスクリプトを読込みます。

<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の使い方について紹介してきました。
少し前までは、jQueryaxiosなどの外部ライブラリでAJAX処理をするのが一般的でしたが、Fetch APIの登場によって、標準の関数で容易にAJAX処理ができるようになりました。

今後は、Fetch APIが主流になっていきそうなので、注目していきましょう。

スポンサーリンク

QooQ