原生 Ajax 取消方式

对于原生XHR对象来说,取消的ajax的关键是调用XHR对象的.abort()方法,请求被中断之后会触发 onabort 事件不会触发 error 事件

1
2
3
4
5
6
7
8
9
10
11
12
13
let ajax = new XMLHttpRequest();
ajax.open("POST", "/api/sys/listTmallShop");
ajax.send(null);
ajax.onreadystatechange = function () {
if (ajax.readyState === 4) {
console.log(ajax.response);
}
};
ajax.onabort = function () {
console.log("请求被中断");
};
// 立即取消请求
ajax.abort();

通过 abort 方法取消的请求在浏览器端可以方便的看到取消的状态。

image-20200828230322026

jquery 取消方式

由于 jquery 的 ajax 函数会返回一个原生的 xhr 对象所以可以通过这个对象调用原生的 abort 方法取消请求,取消之后会触发 error 事件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var jp = $.ajax({
type: "post",
url: "/api/sys/listTmallShop",
data: {
platform: "TMALL",
page: 1
},
success: function (data) {
console.log("成功了");
console.log(data);
},
error: function (err) {
console.log("取消了");
console.log(err);
}
});
jp.abort();

axios 的取消方式

axios 的取消方式相对复杂一些,但从 API 来看他封装了太多东西,这是一种设计上的缺陷,吐槽完毕之后用还是照样用。无奈!

axios的取消需要使用 CancelToken 获取取消令牌,并且用令牌标识单个请求,之后调用令牌的 cancel 即可取消

1
2
3
4
5
6
7
8
9
10
11
12
13
14
const CancelToken = axios.CancelToken;
const source = CancelToken.source();

axios.post("/api/sys/listTmallShop", null, {
cancelToken: source.token
}).catch(function (thrown) {
if (axios.isCancel(thrown)) {
console.log("取消了", thrown.message);
} else {
console.log("出错了");
}
});

source.cancel("取消原因:老子愿意");

如果多个请求可以多次执行 CancelToken.source() 拿到多个 token对象

除了以上的方式还有一种方式可以取消请求

1
2
3
4
5
6
7
8
9
10
11
12
const CancelToken = axios.CancelToken;
let cancel;

axios.get('/user/12345', {
cancelToken: new CancelToken(function executor(c) {
// An executor function receives a cancel function as a parameter
cancel = c;
})
});

// cancel the request
cancel();

经过测试 axios 立刻取消的请求是不在浏览器网络调试中显示的。