JavaScript 请求取消

使用 XMLHttpRequest、Fetch 和 axios 取消 HTTP 请求

问题

如何在 JavaScript 中取消已发送的 HTTP 请求?

解答

JavaScript 实现异步请求主要依靠 XMLHttpRequest 和 Fetch API。常用的 axios 库基于 XMLHttpRequest 封装。下面分别介绍三种方式如何取消请求。

取消 XMLHttpRequest 请求

使用 XMLHttpRequest.abort() 方法取消请求:

const xhr = new XMLHttpRequest();
xhr.open('GET', 'http://127.0.0.1:3000/api/get', true);
xhr.send();

setTimeout(() => {
  xhr.abort();
}, 1000);

取消后,readyState 会变为 XMLHttpRequest.UNSENT(0)xhr.status 会被设为 0

取消 Fetch 请求

使用 AbortController API 取消 Fetch 请求:

const controller = new AbortController();

void (async function () {
  const response = await fetch('http://127.0.0.1:3000/api/get', {
    signal: controller.signal,
  });
  const data = await response.json();
})();

setTimeout(() => {
  controller.abort();
}, 1000);

可以在 controller.abort() 中传入取消原因,并通过 try...catch 捕获错误:

try {
  const response = await fetch(url, { signal: controller.signal });
} catch (error) {
  if (error.name === 'AbortError') {
    console.log('请求已取消');
  }
}

取消 axios 请求

axios 同样支持 AbortController

const controller = new AbortController();

void (async function () {
  const response = await axios.get('http://127.0.0.1:3000/api/get', {
    signal: controller.signal,
  });
  const { data } = response;
})();

setTimeout(() => {
  controller.abort();
}, 1000);

注意:axios 之前使用的 CancelToken 方法已被弃用,建议使用 AbortController

关键点

  • XMLHttpRequest 使用 abort() 方法取消请求,取消后 status 变为 0
  • Fetch 和 axios 都使用 AbortController API,通过 signal 参数关联请求
  • AbortController.abort() 可传入取消原因,配合 try…catch 捕获错误
  • axios 的 CancelToken 已弃用,应使用 AbortController 替代