jQuery 请求拦截可以在请求发出前或响应返回后,统一添加一些处理逻辑(比如添加认证信息、处理错误等),提升代码维护性和开发效率。下面为你介绍几种主流的实现方式。
先通过一个表格快速了解几种主要方法:
拦截方法 | 优点 | 缺点 | 适用场景 |
| 配置一次,全局生效;使用简单 | 可能会被后续的 | 添加统一请求头、参数、错误处理、Loading |
全局Ajax事件 | 事件监听方式,不易被覆盖;可绑定多个处理器 | 只能拦截通过 jQuery 发起的请求 | 请求监控、数据采集、统一修改响应数据 |
Ajax-hook | 可拦截所有 XMLHttpRequest | 需要引入额外库;不支持 IE9 以下浏览器 | 需要精细控制、跨库统一处理、Mock数据 |
下面是每种方法的详细说明和代码示例。
🔧 一、使用 $.ajaxSetup()
方法
$.ajaxSetup()
是 jQuery 提供的全局配置方法,可以设置所有 Ajax 请求的默认参数。通过在 beforeSend
等选项中添加回调函数,可以实现请求拦截。
1. 基本请求拦截
你可以在 beforeSend
函数中修改请求参数或添加信息。
$.ajaxSetup({
beforeSend: function(xhr, settings) {
console.log('拦截到请求:', settings.url); // 输出被拦截的请求URL
// 这里可以添加逻辑,例如修改请求参数
// settings.data = "newData"; // 修改发送数据
},
error: function(xhr, status, error) {
console.log('请求错误:', error); // 统一错误处理
}
});
2. 添加全局认证头
在需要身份验证的请求中,可以统一添加 Token。
function getToken() {
// 从本地存储或其他地方获取token的逻辑
return localStorage.getItem('authToken');
}
$.ajaxSetup({
beforeSend: function(xhr, settings) {
// 设置认证头
xhr.setRequestHeader('Authorization', 'Bearer ' + getToken());
}
});
3. 统一添加参数
例如,为所有 GET 请求添加时间戳以防止缓存。
$.ajaxSetup({
beforeSend: function(xhr, settings) {
if (settings.type.toLowerCase() === 'get') {
// 判断URL是否已有参数
var connector = settings.url.indexOf('?') === -1 ? '?' : '&';
settings.url += connector + 'timestamp=' + Date.now();
}
}
});
4. 全局 Loading 效果
可以通过计数器来控制多个请求并发时的 Loading 显示。
var loadingCount = 0; // 请求计数器
$.ajaxSetup({
beforeSend: function(xhr, settings) {
if (loadingCount === 0) {
showLoading(); // 显示Loading效果
}
loadingCount++; // 增加计数
},
complete: function(xhr, status) {
loadingCount--; // 完成时减少计数
if (loadingCount === 0) {
hideLoading(); // 当没有进行中的请求时隐藏Loading
}
}
});
5. 统一处理特定HTTP错误状态码
$.ajaxSetup()
的 statusCode
选项允许你为特定的 HTTP 状态码注册回调函数。
$.ajaxSetup({
statusCode: {
404: function() {
alert('请求的服务不存在(404)');
},
500: function() {
alert('服务器内部错误(500)');
},
401: function() {
// 未授权,跳转到登录页
alert('登录已过期,请重新登录');
window.location.href = '/login';
},
403: function() {
alert('没有权限访问此资源(403)');
}
}
});
💡 注意:$.ajaxSetup()
的配置是全局的,后续的调用会覆盖之前的设置。在大型项目或多人协作中,应谨慎使用,避免相互干扰。
🧩 二、使用 jQuery 全局 Ajax 事件处理器
jQuery 提供了一套全局的 Ajax 事件方法,如 .ajaxSend()
, .ajaxSuccess()
, .ajaxError()
, .ajaxComplete()
。它们可以监听到页面上所有由 jQuery 发出的 Ajax 请求,并执行相应的回调函数。
1. 请求发送前 (ajaxSend
)
$(document).ajaxSend(function(event, jqXHR, ajaxOptions) {
// event: 事件对象
// jqXHR: jqXHR 对象
// ajaxOptions: 本次请求的配置参数
console.log('发送请求到: ', ajaxOptions.url);
// 可以在这里统一添加请求头
jqXHR.setRequestHeader('X-Custom-Header', 'CustomValue');
});
2. 请求成功时 (ajaxSuccess
)
$(document).ajaxSuccess(function(event, jqXHR, ajaxOptions, data) {
// data: 服务器返回的数据
console.log('请求成功: ', ajaxOptions.url, data);
// 可以在这里对返回数据进行统一预处理
});
3. 请求失败时 (ajaxError
)
$(document).ajaxError(function(event, jqXHR, ajaxOptions, thrownError) {
// thrownError: 错误信息
console.error('请求失败: ', ajaxOptions.url, thrownError);
// 统一错误处理,例如显示通知
showErrorNotification('请求发生错误: ' + thrownError);
});
4. 请求完成时 (ajaxComplete
)
无论成功或失败都会触发。
$(document).ajaxComplete(function(event, jqXHR, ajaxOptions) {
console.log('请求完成: ', ajaxOptions.url);
// 可以在这里做一些清理工作
});
💡 提示:与 $.ajaxSetup()
不同,全局事件处理器可以绑定多个,且不会相互覆盖。它们更适合在模块化开发中各自添加独立的处理逻辑。
⚙️ 三、使用第三方库 Ajax-hook
如果需要拦截的请求不仅来自 jQuery,还包括其他库或原生代码发出的 XMLHttpRequest,可以使用 Ajax-hook 这样的库。
1. 引入并配置 Ajax-hook
首先引入库,然后设置代理。
<script src="path/to/ajaxhook.min.js"></script>
// 拦截所有 XMLHttpRequest 请求
proxy({
// 请求发起前进入
onRequest: (config, handler) => {
console.log('拦截到请求: ', config.url);
// 可以修改 config 中的任何参数,如 url, method, headers, async, data 等
config.headers['X-Token'] = getToken();
handler.next(config); // 继续执行请求
},
// 请求成功后进入
onResponse: (response, handler) => {
console.log('收到响应: ', response.response);
// 可以修改响应数据
// response.response = modifiedData;
handler.next(response);
},
// 请求发生错误时进入(如超时)
onError: (err, handler) => {
console.log('请求错误: ', err.type);
handler.next(err);
}
});
2. 卸载拦截
如果需要取消拦截,可以调用 unHookAjax()
方法。
unHookAjax();
⚠️ 注意:Ajax-hook 使用了 ES5 的 getter
/setter
,因此不支持 IE9 以下浏览器。
💎 总结与选择建议
选择哪种方式,主要看你的具体需求:
- 如果你的项目主要使用 jQuery 进行请求,只需要统一添加一些 headers、参数或错误处理,那么
$.ajaxSetup()
最简单直接。 - 如果你希望以事件监听的方式处理请求,或者需要为不同模块独立添加处理逻辑而不想相互干扰,jQuery 全局事件更合适。
- 如果你需要拦截页面上所有的 Ajax 请求(包括其他库发起的),或者需要非常精细地控制请求和响应的每一个环节(甚至修改原生方法),那么 Ajax-hook 功能最强大。
希望这些信息能帮助你有效地实现 jQuery 的请求拦截!