Fetch 參考: https://developers.google.com...
如今可能還有一些很舊的程序還在使用XHR,相似下面的寫法:php
const request = new XMLHttpRequest() request.responseType = 'json' request.open('GET', '/url', true) request.onload = () => { console.log(request.response) } request.onerror = () => { console.log('shits happen!') } request.send(null)
這樣子使用XHR進行異步訪問、讀取資源顯得很繁瑣,相對比Fetch()容許你建立相似XHR的network訪問,可是使用更簡單並且乾淨的API,不須要屢次回調而且記住XHR複雜的API。Fetch API底層是經過Promises實現。
XMLHttpRequest 一個相對完整的XMLHttpRequest至少須要監聽兩個事件(onload、onerror)來實現成功和失敗的回調,以及調用open()和send()web
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 一個簡單的Fetch例子以下:json
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); });
Fetch的語法更加語義化、比較好理解。在上面的例子裏咱們先判斷response的status碼,若是是200咱們纔將response解析爲JSON
fetch()請求返回的response是Stream對象,所以咱們調用response.json時因爲異步讀取流對象因此返回的是一個Promise對象。
Fetch用async優化代碼 因爲Fetch底層是用Promise實現,咱們能夠直接用async來優化上面的代碼,減小回調,使其更加語義化、容易理解api
async function geturl(){ try{ let res = await fetch('./api/some.json') if(res.status == 200){ console.log(await res.text()) } } catch(err){ console.log(err) } }
Response元數據 在上面的例子裏,咱們瞭解了Response對象的status狀態以及怎麼把response對象轉換爲JSON對象,讓咱們來看看Response對象的其餘元數據:安全
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); });
Response類型 當咱們發起一個Fetch請求時,返回的response響應會自帶一個response.type屬性(basic、cors、opaque)。response.type屬性說明了異步資源的來源,同時還有相應的處理方式。
當咱們發起一個同源請求時,response.type爲basic,並且你能夠從response讀取所有信息。
若是咱們訪問一個非同源域名,而且有返回相應的CORs響應頭時,那麼該請求類型是cors。cors和basic很類似,就除了cors響應裏你沒法訪問cookie
Cache-Control
,app
Content-Language
,cors
Content-Type
,異步
Expires
,async
Last-Modified
和
Pragma
當咱們對一個不一樣源的域名發起請求時,若是返回的響應頭部沒有CORS信息,那麼這個response對應的類型就是opaque類型。一個opaque響應是沒法讀取返回的數據、狀態,甚至沒法肯定這個請求是否成功。
咱們能夠自定義Fetch請求的模式,要求返回對應類型的響應,有如下幾種響應:
same-origin 只返回同源請求,其餘類型會被reject
cors 接收同源、非同源請求,返回有CORs頭部的響應
cors-with-forced-preflight 在發出請求前會先作一次安全性檢查
no-cors 用來發起沒有CORS頭部而且非同源請求,而且會返回opaque響應。可是目前這種類型只能在Service Worker裏使用,在window.fetch裏不能用
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) });
承諾鏈 由於Fetch返回的response是基於Promise實現,因此咱們能夠像鏈條同樣把幾個Promise串接起來,以下所示:
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); });
固然了,咱們也能夠用async進行代碼優化
async function geturl(url){ try { let res = await fetch(url) if(res.status >= 200 && res.status < 300){ console.log('Request succeeded with JSON response', await res.json()) } }catch (err){ console.log(err) } } geturl('users.json')
Post請求 當咱們使用Fetch發起Post請求時,須要手動設置method參數和body參數,以下:
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); });
若是沒有顯式指定method參數,那麼默認Get請求
帶Cookie發送請求 若是咱們想要在異步請求中帶上cookie參數,那麼須要顯式指定credentials參數:
fetch(url, { credentials: 'include' })
轉載於猿2048:→《淺談 Fetch》