JS取消HTTP网络请求的方法总结
如何取消网络请求呢?在前端通常使用网络HTTP请求API有:XMLHttpRequest
和 Fetch
,常用的请求库"jQuery","Axios"
jQuery.ajax,XMLHttpRequest都是基于XMLHttpRequest的网络请求库.
我们来看一下,如何取消正在进行中的网络请求.
有一个http://127.0.0.1:9501/api/get
接口,延迟1秒钟返回结果.
XMLHttpRequest
通过abort()
方法取消请求,status状态码被设置为0
const xhr = new XMLHttpRequest();
xhr.open('GET', 'http://127.0.0.1:9501/api/get', true);
xhr.send();
xhr.abort();
参考:
https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest/abort
监听取消事件:
xhr.addEventListener('abort', (e)=>{
console.log(e.target.status);// 0
});
jQuery Ajax 如何取消呢?
jQuery.ajax是基于xmlHttpRequest的.
参考:https://api.jquery.com/jQuery.Ajax/#jqXHR
通过jqXHR取消
var $ajax=$.ajax({
method:"get",
url:'http://127.0.0.1:9501/get.php',
success:(res)=>{console.log(res)},
error:(e)=>{console.log(e.status,e.statusText)},
})
$ajax.abort();
通过原生XHR取消
通过 $.ajaxSettings.xhr()
获取原生xhr.也可以直接new XMLHttpRequest
取消请求,可以用jquery的abort()
也可以用原生的abort()
var xhr=$.ajaxSettings.xhr();
// var xhr=new XMLHttpRequest();
var $ajax=$.ajax({
method:"get",
url:'http://127.0.0.1:9501/get.php',
success:(res)=>{console.log(res)},
error:(e)=>{console.log(e)},
xhr:()=>xhr,
})
xhr.addEventListener('abort', (e)=>{
console.log(e.target)
});
// $ajax.abort();
xhr.abort();
原生abort与jQuery的abort的有什区别呢?
$ajax.abort可以自定义错误类型,error可以监听到错误回调.
原生xhr只能获取一个error类型.
$ajax.abort("手动取消了")
通过AbortController取消ajax请求.
jquery不支持signal参数,但我们可以通过beforeSend来绑定事件.
const controller = new AbortController();
const signal = controller.signal;
$.ajax({
method:"get",
url:'http://127.0.0.1:9501/get.php',
success:(res)=>{console.log(res)},
error:(e)=>{console.log(e)},
beforeSend:(jqXhr,ajaxSettings)=>{
signal.addEventListener("abort",function(){
jqXhr.abort("AbortController 来取消");
})
}
})
controller.abort();
效果也一样的.
Fetch取消请求
Fetch 也是通过 AbortController api 来取消请求的.
参考:https://developer.mozilla.org/zh-CN/docs/Web/API/AbortController
controller = new AbortController();
const signal = controller.signal;
fetch('http://127.0.0.1:9501/get.php', { signal })
.then((response) => {
console.log('成功', response);
})
.catch((err) => {
console.error('失败',err);
});
controller.abort();
事件监听:
signal.addEventListener('abort', () => {
console.log('请求被取消了');
});
或者
signal.onabort = () => {
console.log('请求被取消了');
};
Axios 取消请求
AbortController方式取消
从v0.22.0版本之后,支持AbortController
方式取消
参考: https://axios-http.com/zh/docs/cancellation
const controller = new AbortController();
axios.get('http://127.0.0.1:9501/get.php', {
signal: controller.signal
}).then((response)=> {
console.log("ok",response)
}).catch((err)=>{
console.error("err",err);
});
controller.abort()
CancelToken 方式取消 (deprecated
)
此 API 从 v0.22.0 开始已被弃用.
API与AbortController 使用相
const CancelToken = axios.CancelToken;
const source = CancelToken.source();
axios.get('http://127.0.0.1:9501/get.php', {
cancelToken: source.token
}).then((response)=> {
console.log("ok",response)
}).catch((err)=>{
console.error("err",err);
});
source.cancel("取消");
总结
需要取消网络请求的场景:
- 耗时太长的请求,我们需要提前那取消
- 无用的网络请求或错误造成的网络请求,避免占用太多资源,取消那掉.
- 路由跳转时,页面上还残留很多请求时.
- 逻辑关系的请求,比如订单详情要获取很多补充信息,但是那业务已经不需要这个订单,其他辅助请求就没必要继续.
批量请求:controller.signal
可以共用,多个请求用一个信号时,可以同时取消.
windows.stop()
可以取消掉页面上的所有请求,包括像图片资源等.
原作者:阿金
本文地址:https://hi-arkin.com/archives/resquest-abort.html