前端進階(2)使用fetch/axios時, 如何取消http請求

Jack Niu發表於2021-04-25

前端進階(2)使用fetch/axios時, 如何取消http請求

1. 需求

現在前端都是SPA,我們什麼時候需要取消HTTP請求呢?

  1. 當我們從一個頁面跳轉到另外一個頁面時,如果前一個頁面的請求還沒有返回,那麼我們希望取消前一個頁面的請求
  2. 某些操作耗時比較長(不能是儲存等操作哦),如果使用者不想等待呢,取消了操作,對應我們也需要取消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. 總結

  1. fetchAbortController整合:我們將signal屬性作為可選引數(option)進行傳遞,之後 fetch 會監聽它,因此它能夠中止 fetch.
  2. AbortController 是可伸縮的,可以用於一次性終止多個請求
  3. 參考fetch的實現,我們自己的程式碼也完善一下,實現基於AbortController操作取消操作;
  4. axios 預設支援Abort操作;

相關文章