本文講解瀏覽器請求的發展歷程,從傳統web應用到ajax,再到jquery,直到目前最爲流行的axios。(重點詳細講,沒用過的寫個思想)javascript
傳統的網頁(不使用 AJAX)若是須要更新內容,必需重載整個網頁。過程是用戶在客戶端觸發HTTP請求,服務器處理請求並返回新的HTHL頁到客戶端,客戶端再從新讀取整個頁面。即便很小的交互,也要完成上述過程,致使浪費帶寬且交互響應很慢。vue
在這個背景下,出現了能夠更新部分網頁數據的Ajax技術。java
AJAX即 Asynchronous JavaScript and XML。它不是新的編程語言,而是在不從新加載整個頁面的狀況下,與服務端交換數據並更新部分網頁的技術。node
Ajax 的工做原理至關於在用戶和服務器之間加了—箇中間層,使用戶操做與服務器響應異步化,而且肯定須要從服務器讀取新數據時再由Ajax引擎代爲向服務器提交請求,像—些數據驗證和數據處理等都交給Ajax引擎本身來作,並不提交給服務端,提高性能。jquery
Ajax 核心由 XMLHTTPRequest、JavaScript、DOM 對象組成,經過XmlHttpRequest對象來向服務器發異步請求,從服務器得到數據,而後用 JavaScript 來操做 DOM 而更新頁面。webpack
const xmlHttp = new XMLHttpRequest()
// 發送請求
xmlHttp.open('GET', 'text1.txt', true) // open(method,url,async)
xmlHttp.send()
// 響應處理
xmlHttp.onreadystatechange = function () {
// 請求已完成,且響應就緒
if (xmlHttp.readyState === 4 && xmlHttp.status === 200) {
document.getElementById('div1').innerHTML = xmlHttp.responsText
}
}
複製代碼
優勢:ios
缺點:git
由於不一樣的瀏覽器對 AJAX 的實現並不相同,因此編寫統一的 AJAX 代碼相對複雜。例如IE五、IE6沒有XMLHttpRequest對象,而是ActiveXObject。github
Jqury 庫對 AJAX 進行了封裝,使得咱們能夠經過更爲簡單統一的方式實現 AJAX 功能,同時可以把這些外部數據直接載入網頁的被選元素中。web
傳統ajax(指的是 XmlHttpRequest,即XHR)已經逐漸被Fetch替代。緣由:
fetch(url).then(function(response) {
return response.json();
}).then(function(data) {
console.log(data);
}).catch(function(e) {
console.log("Oops, error");
});
// 使用 ES6 的 箭頭函數 後:
fetch(url).then(response => response.json())
.then(data => console.log(data))
.catch(e => console.log("Oops, error", e))
複製代碼
fetch的原生支持並很差,經過引入polyfill來支持主流瀏覽器。實質是對於不支持 fetch api 的瀏覽器,使用 XMLHttpRequest 模擬實現 fetch api。
關鍵源碼:
if (self.fetch) {
return
}
...
self.fetch = function(input, init) {
return new Promise(function(resolve, reject) {
var request = new Request(input, init)
var xhr = new XMLHttpRequest()
xhr.onload = function() {...}
}
}
複製代碼
plato((項目採用的vue腳手架)引入方法:
// src/polyfills/index
import 'whatwg-fetch'
// webpack.config.bable.js
entry: {
app: [
paths.src('polyfills/index.js'), // 加載 polyfills
paths.src('index.js')] // 加載入口
}
複製代碼
和Jquery.ajax()的區別
服務器返回 404,500 錯誤碼時並不會reject,只有網絡錯誤或者其餘緣由致使請求不能完成時,fetch 纔會被 reject。爲了保證reject HTTP錯誤狀態,可作以下處理:eg:全部非2xx的錯誤碼都拋出錯誤異常。 (----- 很差用,有時候須要作處理)
function checkStatus(response) {
if (response.status >= 200 && response.status < 300) {
return response
} else {
var error = new Error(response.statusText)
error.response = response
throw error
}
}
function parseJSON(response) {
return response.json()
}
fetch('/users')
.then(checkStatus)
.then(parseJSON)
.then(function(data) {
console.log('request succeeded with JSON response', data)
}).catch(function(error) {
console.log('request failed', error)
})
複製代碼
plato(項目採用的vue腳手架)實現建request.js
const body = await getBody(res)
if (res.status >= 200 && res.status < 400) {
return body
} else {
throw body
}
async function getBody (res) {
const type = res.headers.get('Content-Type')
if (type && type.indexOf('json') !== -1) {
return await res.json()
}
const body = await res.text()
try {
return JSON.parse(body)
} catch (error) {
return { body }
}
}
複製代碼
Fetch 請求默認是不帶 cookie 的,並且也不接收cookie。
發送cookie
接收cookie
同XHR相同, 從服務端返回的響應頭Set-Cookie
是一個被禁的字段,因此不能經過response.headers.get()
來獲取。獲取cookie應該是瀏覽器的職責,經過document.cookie
來實現。
USV字符串
,包含要獲取資源的URL基於Promise的HTTP庫,用於瀏覽器端和Node.js端, 底層實現也是封裝XMLHttpRequest。
Why axios:
特色
參考: