フェッチの概要

さようならXMLHttpRequest!



fetch()



使用すると、XMLHttpRequest(XHR)に類似したクエリを作成できます。 主な違いは、Fetch APIがPromisesを使用することです。これにより、よりシンプルでクリーンなAPIを使用でき、悲惨な数のコールバックを回避し、XMLHttpRequestのAPIを覚える必要がなくなります。





Fetch APIは、Chrome 40のグローバルスコープのService Workerとともにユーザーが利用できるようになりましたが、すでにバージョン42ではウィンドウスコープで利用できます。 もちろん、 まだフェッチをサポートしていない他のすべてのブラウザーには、 GitHubからポリファイルがあります。これは現在入手可能です。



シンプルフェッチリクエスト



XMLHttpRequest



fetch



実装された簡単な例を比較することから始めましょう。 この例で行うことは、URLへのリクエストを作成し、レスポンスを取得してJSONとして解析することだけです。



XMLHttpRequest



XMLHttpRequestの例では、 success



error



時に2つのイベントハンドラーをインストールし、 open()



send()



2つのメソッドを呼び出す必要があります。 MDNドキュメントの例



 function reqListener() { var data = JSON.parse(this.responseText); console.log(data); } function reqError(err) { console.log('Fetch Error :-S', err); } var oReq = new XMLHttpRequest(); oReq.onload = reqListener; oReq.onerror = reqError; oReq.open('get', './api/some.json', true); oReq.send();
      
      





フェッチ



フェッチリクエストは次のようになります。

 fetch('./api/some.json') .then( function(response) { if (response.status !== 200) { console.log('Looks like there was a problem. Status Code: ' + response.status); return; } // Examine the text in the response response.json().then(function(data) { console.log(data); }); } ) .catch(function(err) { console.log('Fetch Error :-S', err); });
      
      







まず、応答のステータスを確認し、リクエストが正常に完了したかどうかを確認します(200のステータスが予想されます)。 すべてが正常であれば、応答をJSONとして解析します。



fetch()



への応答はStreamオブジェクトです。 これは、 json()



メソッドを呼び出した結果、Promiseが得られることを意味します。 そのようなオブジェクトからの読み取りは非同期です。



応答メタデータ



前の例では、応答オブジェクトのステータスを確認し、JSONで応答自体を調整する方法を調べました。 アクセスできる残りのメタデータ(ヘッダーなど)を以下に示します。



 fetch('users.json').then(function(response) { console.log(response.headers.get('Content-Type')); console.log(response.headers.get('Date')); console.log(response.status); console.log(response.statusText); console.log(response.type); console.log(response.url); });
      
      





応答タイプ



フェッチリクエストを行うと、レスポンスにはタイプ「basic」、「cors」または「opaque」が与えられます。 これらの「タイプ」は、データがどのリソースから来たかを示し、データ処理プロセスを決定するために使用できます。



同じオリジンにあるリソースに対してリクエストが行われた場合( リクエストが同じサイト内で実行されることを意味します。およそ。 )、レスポンスにはタイプ「basic」が含まれ、そのようなリクエストに対する制限はありません。



あるオリジンから別のオリジンへリクエストが行われた場合(クロスドメインリクエスト)、その結果、 CORSヘッダーが返された場合、タイプは「cors」になります。 タイプが「cors」と「basic」のオブジェクトはほとんど同じですが、「cors」は「Cache-Control」、「Content-Language」、「Content-Type」、「Expires」にアクセスできるメタデータを多少制限します。 「最終変更」および「プラグマ」。



「不透明」に関しては、CORS要求が実行されたが、リモートリソースがCORSヘッダーを返さない場合に発生します。 このタイプのリクエストはデータまたはステータスヘッダーへのアクセスを提供しないため、リクエストの結果を判断することはできません。 fetch()



現在の実装の一部として、ウィンドウスコープからCORS要求を実行することはできません。 ここにその理由を示します。 この機能は、ウィンドウオブジェクトからCache APIにアクセスできるようになったらすぐに追加する必要があります。



予想されるクエリモードを決定して、間違ったタイプのクエリ結果をフィルタリングできます。 要求モードは次のように設定できます。



-「同じオリジン」は、同じオリジンのリクエストに対してのみ正常に実行され、他のすべてのリクエストは拒否されます。

-「cors」は「same-origin」と同じように機能し、サードパーティのサイトが対応するCORSヘッダーを返す場合、サードパーティのサイトにリクエストを作成する機能を追加します。

-「cors-with-forced-preflight」は「cors」と同じように機能しますが、要求の前に検証のために常にテスト要求送信します

-「no-cors」は、発信元へのリクエストを実行する必要がある場合に使用されます。リクエストはCORSヘッダーを送信せず、実行結果は「不透明」タイプのオブジェクトです。 上記のように、現時点ではウィンドウウィンドウではこれは不可能です。



要求モードを決定するには、要求への2番目のパラメーターとしてオプションオブジェクトを追加し、このオブジェクトに「モード」を設定します。



 fetch('http://some-site.com/cors-enabled/some.json', {mode: 'cors'}) .then(function(response) { return response.text(); }) .then(function(text) { console.log('Request successful', text); }) .catch(function(error) { log('Request failed', error) });
      
      





約束の鎖



Promiseの優れた機能の1つは、それらをチェーンでグループ化する機能です。 fetch()



スコープでそれらについて話すと、リクエスト間のロジックを「いじる」ことができます。



JSON APIを使用している場合、ステータスを確認し、各応答のJSONを解析する必要があります。 Promisesが返す個別の関数としてステータス解析とJSONを定義することにより、コードを簡素化できます。 データ自体の処理と、もちろん例外についてのみ考える必要があります。



 function status(response) { if (response.status >= 200 && response.status < 300) { return Promise.resolve(response) } else { return Promise.reject(new Error(response.statusText)) } } function json(response) { return response.json() } fetch('users.json') .then(status) .then(json) .then(function(data) { console.log('Request succeeded with JSON response', data); }).catch(function(error) { console.log('Request failed', error); });
      
      





response.status



をチェックし、結果を返す関数を定義します: Promise.resolve()



またはPromise.reject()



。 これはチェーンで呼び出される最初のメソッドであり、成功すると( Promise.resolve()



)、次のメソッドが呼び出されますPromise.resolve()



fetch()



、これは再びresponse.json()



からPromiseを返します。 この呼び出しの後、成功すると、準備ができたJSONオブジェクトが作成されます。 解析が失敗すると、Promiseはキャンセルされ、例外条件がトリガーされます。



ただし、ここで最も良いのは、アプリケーション内のすべてのフェッチリクエストにこのようなコードを再利用できることです。 このようなコードは、保守、読み取り、テストが簡単です。



POSTリクエスト



長い間、POSTメソッドを使用して、APIを操作するためのリクエストの「ボディ」にパラメーターを渡す必要があることに驚かないでしょう。

このようなリクエストを実装するには、 fetch()



設定オブジェクトに適切なパラメーターを指定する必要があります。



 fetch(url, { method: 'post', headers: { "Content-type": "application/x-www-form-urlencoded; charset=UTF-8" }, body: 'foo=bar&lorem=ipsum' }) .then(json) .then(function (data) { console.log('Request succeeded with JSON response', data); }) .catch(function (error) { console.log('Request failed', error); });
      
      





フェッチリクエスト経由で認証情報を送信する



いくつかの資格情報(Cookieなど)を使用して要求を送信する場合は、要求オプションで資格情報を設定して、以下を含める必要があります。



 fetch(url, { credentials: 'include' })
      
      





よくある質問



fetch()



リクエストをキャンセルできますか?

これは現時点では不可能ですが、GitHubで活発に議論されています



求愛者はいますか?

はい



サービスワーカーにはno-corsが実装されているが、ウィンドウには実装されていないのはなぜですか?

これはセキュリティ上の理由で行われました。 詳細はこちらをご覧ください



All Articles