さようなら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が実装されているが、ウィンドウには実装されていないのはなぜですか?
これはセキュリティ上の理由で行われました。 詳細はこちらをご覧ください 。