前言:
官方推薦是網絡請求Fetch 今天記錄下這個Fetch
片段一:不同
Ajax JQuery-Ajax axios fetch差別:
傳統 Ajax 指的是 XMLHttpRequest(XHR)最早出現的發送後端請求技術,隸屬于原始js中,核心使用XMLHttpRequest對象
JQuery-Ajax 是對原生XHR的封裝,除此以外還增添了對JSONP的支援
axios 從浏覽器中建立XMLHttpRequest 從node層發起http請求 支援 Promise API
自動轉json 用戶端支援防止CSRF(因為從cookie裡面擷取key值後發送到服務端會檢測).提供了一些并發請求的接口
Fetch 是基于promise設計的 脫離了XHR
符合關注分離,沒有将輸入、輸出和用事件來跟蹤的狀态混雜在一個對象裡 .更好更友善的寫法
片段二:缺點
fetch隻對網絡請求報錯,對400,500都當做成功的請求,伺服器傳回 400,500 錯誤碼時并不會 reject,隻有網絡錯誤這些導緻
請求不能完成時才會被 reject。
fetch預設不會帶cookie,需要添加配置項: fetch(url, {credentials: 'include'})
fetch沒有辦法原生監測請求的進度,而XHR可以
片段三:真實的fetch
fetch 是一個 low-level 的 API,它注定不會像你習慣的 $.ajax 或是 axios 等庫幫你封裝各種各樣的功能或實作。
也正是因為這個定位,在學習或使用 fetch API 時,你會遇到不少的挫折。
片段四:請求比你想象的要複雜
這是我對fetch的第一眼認識:
fetch('http://abc.com/tiger.png');
預設是get方法的form-data(也就是headers: {'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'})
原來需要 new XMLHttpRequest 等小十行代碼才能實作的功能如今一行代碼就能搞定,着實讓人心動!
很可能會得到一個 401 Unauthorized 的結果,為什麼?
會發現原來 fetch 在發送請求時預設不會帶上 Cookie!
你需要:
fetch('/api/add?name=lucy', {
credentials: 'include',
...
});
理,如果你需要 POST 一個 JSON 到服務端,你需要這樣做:
fetch('/api/add', {
method: 'POST',
credentials: 'include',
headers: {
'Content-Type': 'application/json;charset=UTF-8'
},
body: JSON.stringify({name: 'lucy'})
});
片段五 錯誤處理,比你想象的複雜
按照 MDN 的說法,fetch 隻有在遇到網絡錯誤的時候才會 reject 這個 promise,比如使用者斷網或請求位址的域名無法解析等。
是以隻要伺服器能夠傳回 HTTP 響應(甚至隻是 CORS preflight 的 OPTIONS 響應),promise 一定是 resolved 的狀态。
你的404,513,502等一律通過。這個就尴尬了。
判斷一個 fetch 請求是不是成功呢?你得用 response.ok 這個字段。
fetch('xx.png')
.then((response) => {
if (response.ok) {
console.log('ok');
} else {
thorw new error('network error');
}
})
.catch(() => {
console.log('error');
});
對資料格式處理
fetch('/api/user.json?id=2') // 服務端傳回 {"name": "test", "age": 1} 字元串
.then((response) => {
// 這裡拿到的 response 并不是一個 {name: 'test', age: 1} 對象
return response.json(); // 将 response.body 通過 JSON.parse 轉換為 JS 對象
})
.then(data => {
console.log(data); // {name: 'test', age: 1}
});
啰嗦一句:
fetch 不支援同步請求 fetch不支援取消一個請求(使用 XMLHttpRequest 你可以用
xhr.abort()
方法取消一個請求) fetch 無法檢視請求的進度(使用 XMLHttpRequest 你可以通過
xhr.onprogress
回調來動态更新請求的進度)