高级前端html【Q493】如何取消请求的发送

如何取消请求的发送

Issue 欢迎在 Gtihub Issue 中回答此问题: Issue 502

Author 回答者: evle

根据发送网络请求的API不同,取消方法不同

  • xhr
  • fetch
  • axios

如果使用XMLHttpRequest发送请求可以使用XMLHttpRequest.abort()

如果使用fetch发送请求可以使用AbortController

const controller = new AbortController();
const signal = controller.signal;
fetch('https://somewhere', { signal })
controller.abort()

如果使用axios,取消原理同fetch

var CancelToken = axios.CancelToken;
var source = CancelToken.source();

axios.get('/https://somewhere', {
  cancelToken: source.token
}

source.cancel()

Author 回答者: shfshanyue

001 XHR 使用 xhr.abort()

const xhr = new XMLHttpRequest(),
  method = "GET",
  url = "https://developer.mozilla.org/";
xhr.open(method, url, true);
 
xhr.send();
 
// 取消发送请求
xhr.abort();

002 fetch 使用 AbortController

AbortController 文档见 AbortSignal - MDN,它不仅可以取消 Fetch 请求发送,同样也可以取消事件的监听(通过 addEventListener 的第三个参数 signal 控制)

  1. 发送请求时使用一个 signal 选项控制 fetch 请求
  2. control.abort() 用以取消请求发送
  3. 取消请求发送之后会得到异常 AbortError
const controller = new AbortController()
const signal = controller.signal
 
const downloadBtn = document.querySelector('.download');
const abortBtn = document.querySelector('.abort');
 
downloadBtn.addEventListener('click', fetchVideo);
 
// 点击取消按钮时,取消请求的发送
abortBtn.addEventListener('click', function() {
  controller.abort();
  console.log('Download aborted');
});
 
function fetchVideo() {
  ...
  fetch(url, {signal}).then(function(response) {
    ...
  }).catch(function(e) {
   // 请求被取消之后将会得到一个 AbortError
    reports.textContent = 'Download error: ' + e.message;
  })
}

003 Axios: xhrhttp/https

Axios 中通过 cancelToken 取消请求发送

const CancelToken = axios.CancelToken;
const source = CancelToken.source();
 
axios
  .get("/user/12345", {
    cancelToken: source.token,
  })
  .catch(function (thrown) {
    if (axios.isCancel(thrown)) {
      console.log("Request canceled", thrown.message);
    } else {
      // handle error
    }
  });
 
axios.post(
  "/user/12345",
  {
    name: "new name",
  },
  {
    cancelToken: source.token,
  },
);
 
// cancel the request (the message parameter is optional)
source.cancel("Operation canceled by the user.");

而其中的原理可分为两部分

Author 回答者: shfshanyue

@evle 可以使用 js 代码高亮一下,其实 CancelToken 的底部原理是基于 xhr 的