Implementation of Ajax Interceptor
1. 拦截器
拦截器的设置可以让我们在发出 request 或接到 response 之前做一些事情,例如改变 response的数据格式,或是根据不同 request 来添加不同的config 等。请求拦截器的即在请求发送前进行的操作,如设置是否需要token;响应拦截器的即接收到响应后进行操作,如通过状态码设置响应失败的跳转等
若对Ajax的基本使用还不熟悉推荐先看看博客:AJAX详解
2.原生AJAX实现拦截器
需要改变send方法,XMLHttpRequest.prototype.send
在其原型中重新定义了send函数。
const intercept = (method, url, requestCallback, responseCallback) => {
let xhr = new XMLHttpRequest();
//修改原型的open和send方法来创建请求和响应拦截器
let open = XMLHttpRequest.prototype.open;
let send = XMLHttpRequest.prototype.send;
XMLHttpRequest.prototype.open = function () {
requestCallback();
open.call(this, method, url);
};
XMLHttpRequest.prototype.send = function () {
//当Ajax的状态码改变时调用
this.addEventListener('readystatechange', function () {
//请求成功时调用,也可设置别的状态码时调用的函数
if (this.readyState === 4 && this.status === 200) {
//响应拦截器,返回有用的data
let response = JSON.parse(this.responseText);
responseCallback(response.data);
}
});
send.apply(this, arguments); //改变send函数的调用对象
};
xhr.open();
xhr.send();
};
let foo = function () {
console.log('发送请求的操作');
};
let fn = function (data) {
//对响应数据处理后的返回值
console.log(data);
};
//使用
intercept('get', 'https://reqres.in/api/products/4', foo, fn);
结果:
参考资料:
StackOverflow
可传入多个ajax拦截器的完整代码:GitHub
3.使用JQ的ajax实现拦截器
可以调用jQuery自带的api:$.ajaxSetup
和beforeSend
$.ajaxSetup({
url: 'https://reqres.in/api/users/3',//测试接口,可直接使用
//该函数将在发送请求之前运行
beforeSend() {
console.log('发送请求前的操作');
},
dataFilter: function (data, type) {
data = JSON.parse(data);
console.log(data);
//对响应数据进行处理,直接返回响应数据中有用的data
return JSON.stringify(data.data)
},
success: function (data) {
//拿到的为响应数据中的data
console.log(data);
},
});
//调用ajax,可传入自己设置的url,type,success,error,
// 但async、headers等参数的默认值已被$.ajaxSetup()更改
$.ajax({
url:'https://reqres.in/api/products/3'
});
该$.ajaxSetup()方法的设置将应用于整个页面的全局 AJAX 属性
beforeSend :此事件在 Ajax 请求开始之前触发,允许您修改 XMLHttpRequest 对象(如设置附加标头等)
dataFilter:用于处理 XMLHttpRequest 的原始响应数据的函数。这是一个预过滤功能,用于清理响应
complete: 请求完成时要调用的函数(在执行success和error回调之后)