參考: developers.google.com/web/updates…javascript
如今可能還有一些很舊的程序還在使用XHR,相似下面的寫法:java
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實現。web
一個相對完整的XMLHttpRequest至少須要監聽兩個事件(onload、onerror)來實現成功和失敗的回調,以及調用open()和send()json
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
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對象。cookie
因爲Fetch底層是用Promise實現,咱們能夠直接用async來優化上面的代碼,減小回調,使其更加語義化、容易理解app
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對象的status狀態以及怎麼把response對象轉換爲JSON對象,讓咱們來看看Response對象的其餘元數據:cors
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);
});
複製代碼
當咱們發起一個Fetch請求時,返回的response響應會自帶一個response.type屬性(basic、cors、opaque)。response.type屬性說明了異步資源的來源,同時還有相應的處理方式。異步
當咱們發起一個同源請求時,response.type爲basic,並且你能夠從response讀取所有信息。
若是咱們訪問一個非同源域名,而且有返回相應的CORs響應頭時,那麼該請求類型是cors。cors和basic很類似,就除了cors響應裏你沒法訪問Cache-Control
,Content-Language
,Content-Type
,Expires
,Last-Modified
和Pragma
當咱們對一個不一樣源的域名發起請求時,若是返回的響應頭部沒有CORS信息,那麼這個response對應的類型就是opaque類型。一個opaque響應是沒法讀取返回的數據、狀態,甚至沒法肯定這個請求是否成功。
咱們能夠自定義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')
複製代碼
當咱們使用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參數,那麼須要顯式指定credentials參數:
fetch(url, {
credentials: 'include'
})
複製代碼