请求拦截--XMLHttpRequest、axios、ajax、fetch

1,449 阅读2分钟

首先, 假设每一种方案请求的接口都是url,且此请求会延迟一秒后返回test success结果。

var url = 'http://localhost:3333/test';

原生XMLHttpRequest 请求拦截

原生异步请求中,XMLHttpRequest实例化对象, 本身就有一个 abort方法用于 断开发起的请求。

withCredentials的含义是: 跨域请求是否提供凭据信息(cookie、HTTP认证及客户端SSL证明等) 也可以简单的理解为,当前请求为跨域类型时是否在请求中协带cookie。


var xhr = new XMLHttpRequest();

if('withCredentials' in xhr){
    xhr.withCredentials = true;
}

xhr.open('GET', url);

xhr.send();

xhr.readystatechange = function(){
    if(xhr.readyState === 4 && xhr.status == 200) {
        console.log(xhr.responseText);
    } 
}

setTimeout(function(){
    xhr.abort()  // 20毫秒后, 断开连接
}, 20)

axios 请求拦截

axios中, 请求拦截是有对应的处理方案的。

首先需要创建一个 取消请求的令牌。 方式是, 调用 axios.CancelToken.source() 方法, 假设用token变量接收创建的令牌。

在发起请求时, 给当前请求传一个cancelToken参数, 参数的值为 token.token变量, 即一个取消请求的令牌上的token值。这一步是为了将此令牌和当前请求进行关联。

捕获当前请求的catch, 并在函数体内,通过 axios.isCancel(err)来判断当前的报错是否是取消令牌抛出的。接着就可以在这个分支中编写对应取消后的逻辑了。

以上代码产出如下:

var token = axios.CancelToken.source();

axios.get(url, {
    cancelToken: token.token
}).catch(err => {
    if(axios.isCancel(err)){
        // 请求取消成功 TODO

        throw new Error(err) // 取消请求了!
    }
})

setTimeout(()=> {
    token.cancel('取消请求了!')
},20)


ajax 请求拦截

JQuery上的静态方法 ajax,在发送一个请求时,会返回一个自己封装的请求对象, 在这个对象上就有一个abort方法了。 在合适的地方直接调用此方法即可。

var example = $.ajax({
    method: 'GET',
    url,
    success(res){
        console.log(res);
    }
})


setTimeout(()=>{
    example.abort();
})


fetch 请求拦截

fetch中,断开请求稍微多了一点步骤。 它本身内部并没有封装跟断开请求相关的内容。而是将这部分内容独立出来,并封装在了一个叫做AbortController构造函数上。

逻辑也比较简单, 针对一个请求,生成一个AbortController对象, 并将其实例对象的signal,作为当前请求的一个标志, 同时这一步也是为了将两者关联起来。

如果需要断开请求, 只需要调用一下实例对象上的 abort方法即可。

var abortControl = new AbortController();

fetch(url, {
    method: 'GET',
    signal: abortControl.signal
})

setTimeout(()=>{
    abortControl.abort(); // 手动断掉请求
},20)