layui.ajax全局error回调无法捕获401,因401是http正常响应而非网络错误;必须通过complete回调读取jqxhr.status判断,或在table.render的done中解析res.code,后端需统一响应结构。

layui.ajax 全局 error 回调无法捕获 401?
不能靠 layui.config({ajax: {error: fn}}) 捕获 401,它只处理网络层错误(超时、跨域、连接失败),不拦截 HTTP 状态码。401 是服务端正常返回的响应,必须走响应体解析逻辑。
用 layui.ajax 替代 $.ajax 并手动解析 response.status
layui 自带的 layui.ajax 支持 complete 回调,能拿到原生 jqXHR 对象,其中包含 status 字段。这是唯一可靠方式:
- 所有请求必须统一走
layui.ajax,禁用$.ajax或$.post -
complete在 success/error 后执行,确保无论状态如何都能进入 - 在
complete中判断jqXHR.status === 401,再跳转登录页
layui.use(['jquery', 'layer'], function(){
var $ = layui.jquery, layer = layui.layer;
layui.ajax({
url: '/api/user/info',
method: 'GET',
complete: function(jqXHR) {
if (jqXHR.status === 401) {
localStorage.removeItem('token');
layer.msg('登录已失效,请重新登录', {icon: 7});
setTimeout(function() {
location.href = '/user/login';
}, 1500);
}
}
});
});
table.render 的 401 处理必须写在 done 回调里
table.render 不走 layui.ajax 的全局钩子,它的 done 回调接收三个参数:res、curr、count,但不暴露 jqXHR。所以只能靠后端配合:让接口在 401 时仍返回 200 状态码,但 body 中带 {code: 401, msg: "未授权"},然后在 done 中检查 res.code:
- 后端必须统一响应结构,不能让 401 直接走 HTTP 状态码返回
- 前端在
response.statusName配置为'code',与response.statusCode.logout对齐 - 若坚持用真实 401 状态码,则
table.render会直接进error回调,但此时无法读取响应体,基本不可用
admin.req 的拦截器改写要避开 response.data 嵌套陷阱
layuiAdmin 的 admin.req 默认把响应体塞进 response.dataName(如 'data'),但 401 时后端通常不返回 data 字段,导致 res.data 为 undefined,直接报错。正确做法是:
- 在
config.js的response配置中,去掉对dataName的强依赖 - 改用
parseData函数,在里面先判断原始响应是否含status或code - 不要在
parseData里直接访问res.data.xxx,先做if (!res || typeof res !== 'object')安全校验
真正容易被忽略的是:当后端返回 401 且带完整 JSON body 时,admin.req 仍会尝试解析 data 字段——如果没配 parseData,就静默失败;配了但没判空,就抛 JS 错误而不是跳登录。











