在项目里经常有取消请求的要求,比如超时30秒后取消请求,跳转新页面时取消上个页面的请求,用户手动取消请求等功能,这些场景都需要取消请求。下面来看看axios/fetch/XMLHttpRequest发送请求,如何取消请求。
axios
在axios中想要取消请求,主要有两种方式,一种是使用 CancelToken.source()
工厂函数,一种是使用CancelToken构造函数,两种方式都能够取消请求,一个可用来取消多个请求,一个可以取消单独某个请求。
下面,我们使用CancelToken.source
工厂函数来取消请求
相同的
cancelToken
可以同时取消掉多个请求
const CancelToken = axios.CancelToken;
const source = CancelToken.source();
axios.get('/user/12345', {
cancelToken: source.token
}).then((data) => console.log(data))
.catch((error) => {
// 判断是否为手动取消
if (axios.isCancel(thrown)) {
console.log('请求被手动取消: ', error.message);
} else {
// 处理其他请求错误
}
});
axios.post('/user/12345', {
name: 'new name'
}, {
cancelToken: source.token
})
// 手动取消请求,参数为可选。(GET - /user/12345 和 POST - /user/12345将被取消请求)
source.cancel('用户手动取消请求');
通过CancelToken
构造函数来创建cancelToken
使用
CancelToken
构造函数可以为每个请求生成单独的cancelToken
,用来取消某个单独的请求
const CancelToken = axios.CancelToken;
let cancel;
axios.get('/user/12345', {
cancelToken: new CancelToken((c) => {
// CancelToken参数为一个回调函数,将cancelToken在函数返回
cancel = c;
})
}).then((data) => console.log(data))
.catch((error) => {
// 判断是否为手动取消
if (axios.isCancel(thrown)) {
console.log('请求被手动取消: ', error.message);
} else {
// 处理其他请求错误
}
});
// 取消请求
cancel();
fetch
在fetch请求中,需要使用创建一个新的AbortController
对象,来取消请求,这个对象中有一个signal
属性,将signal
传入fetch请求的配置中,然后我们使用AbortController
的abort
方法可取消此次请求。
const controller = new AbortController();
const { signal } = controller;
fetch("/user/12345", { signal }).then(response => {
console.log('请求成功');
}).catch(err => {
if(err.name === "AbortError") {
// 请求被手动取消
} else {
// 处理错误
}
});
setTimeout(() => {
// 手动取消请求
controller.abort();
}, 1000)
XMLHttpRequest
用XMLHttpRequest发出请求,使用abort()
会中止请求,readyState
会变为XMLHttpRequest.UNSENT
,并且status
状态码会变成为0
const xhr = new XMLHttpRequest(),
method = "GET",
url = "/user/12345";
xhr.open(method, url, true);
xhr.onreadystatechange = function () {
if(xhr.readyState === XMLHttpRequest.UNSENT) {
if (status === 0) {
// 请求被取消
}
} else if(xhr.readyState === XMLHttpRequest.DONE) {
var status = xhr.status;
if (status === 0 || (status >= 200 && status < 400)) {
// 请求成功
console.log(xhr.responseText);
} else {
// 处理错误
}
} else if
};
xhr.send();
setTimeout(() => {
// 手动取消请求
xhr.abort();
}, 1000)
总结
无论是通过axios/fetch/XMLHttpRequest哪种方式发送请求,取消方法都大体类似,都是去调用abort()
方法,然后在错误的回调中判断是否为手动取消请求。