Fetch APIの使い方!JavaScriptでGET/POSTを非同期で送信

2022年6月29日水曜日

Fetch API Javascirpt

t f B! P L

Fetch APIの使い方

スポンサーリンク

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の採用が始まっています。
2021年6月時点の Fetch API対応状況

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

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

最初はシンプルに GETリクエストを送信する方法を紹介します。

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

const response = await fetch("https://httpbin.org/delay/2");
console.log(await response.json())

このように、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://xxxxxxxxxxxx");

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

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

スポンサーリンク
スポンサーリンク

このブログを検索

Profile

自分の写真
Webアプリエンジニア。 日々新しい技術を追い求めてブログでアウトプットしています。
プロフィール画像は、猫村ゆゆこ様に書いてもらいました。

仕事募集もしていたり、していなかったり。

QooQ