- JavaScript
- 2022-05-10 - 更新:2022-05-11
これまで非同期通信といえばXMLHttpRequestでしたが、最近は新たにFetch APIが主流になりつつあるようです。
Fetch APIがいつ定義されたのかは定かではありませんが、HTML Living Standardになった頃でしょうか。
それはともかくFetch APIの使い方を見ていきたいと思います。
まずはこれまでのXMLHttpRequestを確認してみましょう。
XMLHttpRequest
XMLHttpRequestオブジェクトの宣言
let xmlHttp; if(window.XMLHttpRequest) { // code for IE7+, Firefox, Chrome, Opera, Safari xmlHttp = new XMLHttpRequest(); } else { // code for IE6, IE5 xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); }
GETの場合
xmlHttp.open("GET", url, true); xmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8'); xmlHttp.onreadystatechange = function() { if(xmlHttp.readyState == XMLHttpRequest.DONE && xmlHttp.status == 200) { const data = xmlHttp.responseText; // 何らかの処理 } } xmlHttp.send(null);
POSTの場合
xmlHttp.open("POST", url, true); xmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8'); xmlHttp.onreadystatechange = function() { if(xmlHttp.readyState == XMLHttpRequest.DONE && xmlHttp.status == 200) { const data = xmlHttp.responseText; // 何らかの処理 } } xmlHttp.send(param);
Fetch API
Fetch APIの書式は次のようになります。
let promise = fetch(url, [options])
fetchはPromiseオブジェクトを返してくれます。
以下の例では基本的にPOSTでの通信としています。
fetchを使った非同期処理① [ES2015(ES6)]
まずはPromiseチェーンを使って書いてみます。
const fetchPost = (url, param = "") => { fetch(url, { method: "POST", headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' }, body: param }) .then((response) => { if(!response.ok) { throw new Error(`Error: ${response.status} ${response.statusText}`); } return response.text(); }) .then((data) => { // 何らかの処理 }) .catch((error) => { alert(error); }); }
then
が2つに分かれている理由…
response.text()
メソッドや後述するresponse.json()
メソッド等は非同期のため、2つに分けています。
すぐに処理しようとするとデータが無くてエラーになります。
また、response.text()
及びresponse.json()
は一度しかレスポンスを得られません。
response.text()
を実行した後にresponse.json()
を実行すると処理は失敗します。
response.ok
はHTTPステータスコードが200~299だとtrue
を返します。
fetchを使った非同期処理② [ES2017(ES8)]
今度はasync / await
を使って書いてみましょう。
const fetchPost = async (url, param = "") => { const response = await fetch(url, { method: "POST", headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' }, body: param }); if(response.ok) { const data = await response.text(); // 何らかの処理 } else { alert(`Error: ${response.status} ${response.statusText}`); } }
Promiseチェーンを使ったときよりも更にスッキリしましたね。
fetchを使った非同期通信③ JSONデータ [ES2017(ES8)]
今度はJSONデータを受け渡しするパターンです。
const fetchPostJson = async (url, param = {}) => { const response = await fetch(url, { method: "POST", headers: { 'Content-Type': 'application/json; charset=UTF-8' }, body: JSON.stringify(param) }); if(response.ok) { const data = await response.json(); // 何らかの処理 } else { alert(`Error: ${response.status} ${response.statusText}`); } }
fetchを使った非同期処理④【GETの場合】 [ES2017(ES8)]
GETの場合はかなりシンプルに書くことができますね。
const fetchGet = async (url, param = "") => { const response = await fetch(`${url}?${param}`); if(response.ok) { const data = await response.text(); // 何らかの処理 } else { alert(`Error: ${response.status} ${response.statusText}`); } }
以上です。
公式サイトに対応ブラウザについても記載がありますので、是非参考にしてみてください。
公式サイト:Fetch API – Web API | MDN
参考URL:
https://qiita.com/sotasato/items/31be24d6776f3232c0c0
https://ja.javascript.info/fetch
https://blog.katsubemakito.net/html5/fetch1