1. 需求
現在前端都是SPA,我們什麼時候需要取消HTTP請求呢?
- 當我們從一個頁面跳轉到另外一個頁面時,如果前一個頁面的請求還沒有返回,那麼我們希望取消前一個頁面的請求
- 某些操作耗時比較長(不能是儲存等操作哦),如果使用者不想等待呢,取消了操作,對應我們也需要取消HTTP請求
對於原生的XMLHttpRequest
,是支援取消http請求(abort
)操作的: XMLHttpRequest.abort()
那麼,當我們使用ES6的fetch,或者使用axios庫,如何實現呢?
2. Fetch 取消http請求
fetch與XMLHttpRequest(XHR)類似,是ES6之後瀏覽器(除IE之外)預設支援的http操作函式。可惜不是預設支援abort操作。但我們可以通過AbortController
來實現, 直接上程式碼:
// 宣告AbortController
const controller = new AbortController();
// 正常的http呼叫
fetch('https://jackniu81.github.io', { signal: controller.signal })
.then(r => r.json())
.then(response => {
console.log(response);
})
.catch(err => {
if (err.name === 'AbortError') {
console.log('Fetch was aborted')
} else {
console.log('Error', err)
}
});
// 需要取消請求時,呼叫:
controller.abort()
3. axios取消http請求
axios 已經實現了abort操作,
var source = axios.CancelToken.source();
axios.get('https://jackniu81.github.io', {
cancelToken: source.token
}).catch(function(err) {
if (axios.isCancel(err)) {
// handle our cancel operation
console.log('Request canceled', err.message);
} else {
// handle real error here
}
});
// 需要取消請求時,呼叫:
source.cancel('Abort Request');
4. jquery 取消http請求
$.ajax內部已經實現了abort功能。直接呼叫.abort()
即可。
5. 總結
fetch
與AbortController
整合:我們將signal
屬性作為可選引數(option)進行傳遞,之後 fetch 會監聽它,因此它能夠中止 fetch.- AbortController 是可伸縮的,可以用於
一次性終止多個請求
; - 參考fetch的實現,我們自己的程式碼也完善一下,實現基於AbortController操作取消操作;
- axios 預設支援Abort操作;