非同期通信 fetch
fetch オブジェクトは、XMLHttpRequest(XHR) オブジェクトに代わる、サーバーと対話するためのAPIです。
fetch はプロミス値を返しますので、XMLHttpRequest に比べて、簡略化されて可読性の良いスクリプトを書くことができます。
この記事では、演習用のJSONデータとして MDN が用意しているデータを利用します。
https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json
fetch を使ってサーバーからデータを取り込む方法を説明するのが目的なので、データの中身はあまり気にしないでください。
fetch() メソッド
fetch() メソッドの基本構文
let promise = fetch( URL , {オプション} ) ;非同期関数を使って、サーバーからデータを取得
では、サーバーからデータを取得してみましょう。
非同期関数 ( async / await ) を使って、データを取得してみます。
async function getData() {
const response = await fetch('https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json') ;
const resData = await response.json() ;
console.log( 'response' , response ) ;
console.log( 'resData' , resData ) ;
console.log( resData.squadName ) ; // Super Hero Squad
}
getData() ;
/*
response Response {type: 'cors', url: 'https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json', redirected: false, status: 200, ok: true, …}
resData {squadName: 'Super Hero Squad', homeTown: 'Metro City', formed: 2016, secretBase: 'Super tower', active: true, …}
*/fetch() メソッドは Response オブジェクトを返します。
fetch() メソッドによりサーバーへリクエストが送られると、すぐにプロミスが “pending” で返されます。その後サーバーがヘッダを受け取り通信状態を応答すると、Response オブジェクトで resolve します。Response オブジェクトには通信状態を示す、status (HTTPステータスコード) / ok (HTTPステータスコードが200~299の時 true)などが返されます。

但し、この時点では、サーバーとの通信(リクエスト)が確立されただけで、実際のデータは取得されていません。
Response オブジェクトの json() メソッドにより、JSON として解釈した結果で resolve するプロミスを返します。Responseオブジェクトのストリームを取得して、データを読み取り後JSONとして解釈し、JavaScriptのオブジェクトで resolve します。
エラー処理を入れてみます。
async function postData() {
try {
const response = await fetch('https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json') ;
if ( !response.ok ) {
throw 'FETCH ERROR! HTTP Status:' + response.status ;
}
const resData = await response.json() ;
console.log( response ) ;
console.log( resData ) ;
} catch( e ) { // ***
console.error(e) ;
}
}
postData() ;スクリプトでは Response オブジェクトの ok プロパティでエラー処理の判断をしていますが、status プロパティを使えばもっと詳しくエラー処理をおこなうことも可能です。
プロミスチェーンで書く
非同期関数を使わないスクリプトです。
fetch('https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.jsonX')
.then( ( response ) => {
console.log( response ) ;
return response.json() ;
}).then( ( resData ) => {
console.log( resData ) ;
console.log( resData.squadName ) ; // Super Hero Squad
}).catch( ( e ) => {
console.error( e ) ;
}) ;JSONデータ取得関数にしてみる。
少しだけ汎用性をもたせて、URLとパラメータを渡すとJSON形式でデータが取得できる関数を作成します。
今回は渡したパラメータが、ホスト側で利用されることはありませんが、スクリプトの例としてパラメータを渡しています。
リクエスト先の URL が変わっていますが、POSTする場合はCROS(Cross-Origin Resource Sharing)でエラーとなりますので、ローカル環境にJSONを作成しています。
// 汎用JSON取得関数
async function postData( argURL , argData ) {
try {
const response = await fetch(
argURL , {
method: 'POST' , // メソッドPOST
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify( argData ), // JSONでパラメータを渡します。型は "Content-Type" ヘッダーと一致させる必要があります
}
) ;
if ( !response.ok ) { // fetchのエラーチェック
throw 'FETCH ERROR! HTTP Status:' + response.status ; // fetchでエラーがあればエラーを投げる
}
const resData = await response.json() ; // レスポンスデータのの取得
return { // データの取得状態(true)と取得したJSONデータを返します。
status: true ,
retData: resData ,
} ;
} catch( e ) { // エラー処理
return { // データの取得状態(false)とエラー内容を返します。
status: false ,
retData: e ,
} ;
}
}
// プロフィール表示関数
async function getProfile( argName ) {
data = { name : argName } ;
try {
const res = await postData( 'http://localhost/testsrc/files/superheroes.json' , data) ;
if ( !res.status ) { // データの取得状態のチェック
throw res.retData ; // 正常に取得できなかったらエラーを投げてcatch()で処理する。
}
// データが正常に取得できた処理
const retData = res.retData ;
console.log( argName + ' ' + retData.squadName ) ; // Heroes Super Hero Squad
} catch( e ) { // エラーの処理
console.error(e) ;
}
}
getProfile( 'Heroes' ) ;汎用JSON取得非同期関数 postData は、データ取得URL とパラメータ用データを渡すと、取得状態とデータを受け取ることができます。プロフィール表示関数 getProfileは、この汎用JSON取得非同期関数 postData を使って取得したデータを表示しています。
JSON以外のオブジェクトの取得
今回の例では、JSON データを取得してますが、Response オブジェクトには、それ以外にもメソッドが用意されています。
- Response.arrayBuffer()
レスポンスの本文を表す ArrayBuffer で解決するプロミスを返します。 - Response.blob()
レスポンスの本文を表す Blob で解決するプロミスを返します。 - Response.clone()
Response オブジェクトの複製を生成します。 - Response.error()
ネットワークエラーに関連した新しい Response オブジェクトを返します。 - Response.formData()
レスポンスの本文を表す FormData で解決するプロミスを返します。 - Response.json()
レスポンスの本文のテキストを JSON として解釈した結果で解決するプロミスを返します。 - Response.redirect()
異なる URL で新しい response を生成します。 - Response.text()
レスポンスの本文のテキスト表現で解決するプロミスを返します。
参考リンク
MDN 開発者向けのウェブ技術 > WindowOrWorkerGlobalScope.fetch()
MDN 開発者向けのウェブ技術 > Fetch API
MDN 開発者向けのウェブ技術 > Response
MDN 開発者向けのウェブ技術 > Response.json()
MDN 開発者向けのウェブ技術 > Fetch の使用
ウェブ開発を学ぶ > JavaScript > クライアントサイドWebAPI > サーバからのデータ取得
MDN 開発者向けのウェブ技術 > HTTP > オリジン間リソース共有 (CORS)
MDN 開発者向けのウェブ技術 > JavaScript「再」入門
