Axios 请求取消功能完整指南
1. Axios 请求取消的基本概念
Axios 提供了两种主要方式来取消正在进行的请求:
- CancelToken:通过创建一个取消令牌(cancel token),将其附加到请求中,当需要取消请求时调用
cancel()方法。 - AbortController:基于 Fetch API 的
AbortController实现,通过传递AbortController实例的signal属性来取消请求。
这两种方法各有优缺点,但目前推荐使用 AbortController,因为它是现代浏览器支持的标准方法,而 CancelToken 已被弃用。
2. 使用 CancelToken 取消请求
- 创建 CancelToken 对象
// 创建取消令牌源
const CancelToken = axios.CancelToken
const source = CancelToken.source()
- 将 CancelToken 附加到请求
axios.get('https://api.example.com/data ', { cancelToken: source.token })
.then(response => {
console.log(response.data);
})
.catch(error => {
if (axios.isCancel(error)) {
console.log('请求被取消:', error.message);
} else {
console.error('其他错误:', error);
}
});
- 取消请求
cancelToken.cancel('操作已取消');
需要注意的是,一旦取消请求,CancelToken 的 token 将失效,需要重新创建新的 CancelToken 对象。
3. 使用 AbortController 取消请求
从 Axios v0.22.0 版本开始,推荐使用 AbortController 来取消请求。以下是具体实现步骤:
- 创建 AbortController 实例
const controller = new AbortController();
const signal = controller.signal;
- 将信号传递给 Axios 请求
axios.get('https://api.example.com/data ', { signal })
.then(response => {
console.log(response.data);
})
.catch(error => {
if (error.name === 'AbortError') {
console.log('请求被取消:', error.message);
} else {
console.error('其他错误:', error);
}
});
- 取消请求
controller.abort('操作已取消');
相比 CancelToken,AbortController 更符合现代 Web 标准,并且支持更广泛的浏览器环境。
5.封装在拦截器中
基于 CancelToken
封装请求
import axios from "axios";
const service = axios.create({
baseURL: process.env.VUE_APP_API_BASE_URL,
timeout: 5000,
});
let cancel;
const cancelRequest=(val)=> {
if (cancel) {
cancel(val || 'cancel request');
cancel = null; // 重置请求
}
}
service.interceptors.request.use(
(config) => {
if (cancel) {
cancel();
}
config.cancelToken = new axios.CancelToken(function executor(c) {
cancel = c;
});
return config;
},
(error) => {
return Promise.reject(error);
}
);
service.interceptors.response.use(
(response) => {
return response;
},
(error) => {
if (axios.isCancel(error)) {
console.log("Request canceled:", error.message);
return Promise.reject(error);
}
return Promise.reject(error);
}
);
//将取消请求的方法暴露
service.cancelRequest=cancelRequest
export default service;
触发方式
<template>
<div class="">
<button @click="send">发送请求</button>
<button @click="cancel">取消请求</button>
</div>
</template>
<script>
import http from "@/utils/request";
export default {
data() {
return {
};
},
methods: {
send() {
http
.get("/xxx")
.then((response) => console.log(response.data))
.catch((error) => console.error(error));
},
cancel() {
http.cancelRequest("主动取消了请求");
},
},
};
</script>
基于 AbortController
import axios from 'axios';
const service = axios.create({
baseURL: process.env.VUE_APP_API_BASE_URL,
timeout: 5000,
});
let controller;
const abortRequest=(val) =>{
if (controller) {
controller.abort(val || 'Request canceled ');
controller = null;
}
}
service.interceptors.request.use((config) => {
if (controller) {
abort();
}
controller = new AbortController();
config.signal = controller.signal;
return config;
}, (error) => {
return Promise.reject(error);
});
service.interceptors.response.use((response) => {
return response;
}, (error) => {
if (error.name === 'AbortError') {
console.log('Request canceled:', error.message);
return Promise.reject(error);
}
return Promise.reject(error);
});
service.abortRequest = abortRequest;
export default service;
触发方式
<template>
<div class="">
<button @click="send">发送请求</button>
<button @click="cancel">取消请求</button>
</div>
</template>
<script>
import http from "@/utils/request";
export default {
data() {
return {
};
},
methods: {
send() {
http
.get("/xxx")
.then((response) => console.log(response.data))
.catch((error) => console.error(error));
},
cancel() {
http.abortRequest("主动取消了请求");
},
},
};
</script>
6. Axios 请求取消的注意事项
- 取消时机:只有在请求尚未发送时才能取消(也就是pending时候)。如果请求已经发送,则无法取消。
- 错误处理:当请求被取消时,Axios 会抛出一个错误。可以通过捕获错误并检查其类型来判断是否为取消操作。
- 资源管理:取消请求后,应确保释放相关资源,例如清除存储的取消函数或关闭控制器实例。
7. 实际应用场景
- 用户导航离开页面:当用户点击导航按钮时,可以调用取消函数以停止正在进行的请求。
- 重复请求管理:在短时间内连续发送相同请求时,可以通过取消旧请求来避免重复响应。(通过 URL和参数生成唯一标识符(如
${method}-${url}),用于判断是否为相同请求。) - 动态搜索功能:在用户输入内容变化时,可以取消正在进行的 API 请求以减少资源消耗。
8. 总结
Axios 提供了灵活的请求取消机制,通过 CancelToken 和 AbortController 可以有效管理异步请求。尽管 CancelToken 已被弃用,但 AbortController 是目前推荐的最佳实践。开发者可以根据项目需求选择合适的方法,并注意正确处理取消后的资源释放和错误捕获。