layui table 错误响应被吞是因 parseData 和 done 钩子处理机制不同:parseData 可捕获 JSON 响应并透传错误,done 需手动检查 xhr 对象获取非 JSON 错误;统一错误结构需在 parseData 中判断 code 并返回 msg,非 JSON 场景则在 done 中读取 xhr.responseText 定位问题。
layui table render 报 error 时后端响应被吞了
默认情况下,layui.table.render 遇到 http 非 200 或 json 解析失败,只在控制台打个 error,不暴露原始响应体。你看到的不是“没报错”,而是“错被吃掉了”。
关键在 parseData 和 done 两个钩子:前者能劫持原始响应,后者只能拿到处理后的数据或空对象。
-
parseData是唯一能拿到res(即 xhr.response)的地方,哪怕状态码是 500、401,只要响应体是合法 JSON,它就进得来 - 如果后端返回的是纯文本(比如
"token expired")或 HTML 错误页,parseData根本不会触发——这时要靠done的第三个参数res(注意:这个res是 xhr 对象,不是响应体) - 必须手动检查
xhr.status和xhr.responseText,否则永远不知道后端到底返回了啥
在 parseData 中捕获并透传后端错误字段
假设后端统一用 { "code": 500, "msg": "数据库连接超时", "data": null } 结构,这是最常见也最可控的场景。
直接改写 parseData,把错误信息塞进 msg 字段,再 throw 出去让 layui 显示:
parseData: function(res){
if (res.code !== 0) {
// 把后端 msg 提出来,供 layui 自动提示
return {
code: res.code,
msg: res.msg || '请求异常',
count: 0,
data: []
};
}
return {
code: 0,
msg: '',
count: res.count,
data: res.data
};
}
- layui 只认
code === 0为成功,其它都算失败,并用msg弹出提示 - 别在
parseData里console.log(res)就完事——用户看不到,你也容易漏掉非 JSON 响应 - 如果后端
msg字段名不固定(比如有时叫message),这里就得做兼容判断,而不是硬写res.msg
done 回调里抓取非 JSON 响应(如 502、超时、HTML 错误页)
当后端挂了、Nginx 返回 502、或 PHP Fatal Error 输出了 HTML,parseData 不会执行,但 done 仍会被调用,且第三个参数是原始 xhr 对象。
这时候必须手动读 xhr.responseText:
done: function(res, curr, count, xhr){
if (xhr && xhr.status !== 200) {
console.error('HTTP', xhr.status, xhr.statusText);
console.error('Response:', xhr.responseText.substring(0, 500));
// 这里可以 alert 或调用自定义错误弹窗
}
}
-
xhr.responseText是字符串,可能很长,截取前 500 字足够定位问题 - 注意:某些跨域场景下,
xhr.responseText可能为空(浏览器限制),此时只能依赖xhr.status和xhr.statusText - 不要在
done里重新赋值res——它已经是 parseData 处理后的结果,改了也没用
后端返回格式不统一时的兜底方案
现实里常遇到:登录过期返回 401 + JSON,服务不可用返回 503 + HTML,网关超时返回 504 + 空体。单靠前端很难穷举。
最稳的做法是在请求层统一拦截,而不是等 table 自己处理:
- 用
beforeSend(如果用 jQuery)或全局axios.interceptors预处理所有请求,对非 2xx 响应提前抛错 - 或者在
url配置里不用字符串,改用函数,内部用fetch或axios手动发请求,自己控制错误分支 - layui 本身不支持 Promise,所以别指望
render能 await——错误处理必须前置或降级到 xhr 层
真正难的不是怎么显示错误,而是怎么确保每种异常路径都被覆盖。尤其是 Nginx/网关层的错误,前端连 JSON 都收不到,只能靠 status 和 network 面板反推。









