不能直接改 layui.ajax 或用 $.ajaxSetup,因其被 Layui 封装且不暴露原型链,$.ajaxSetup 在 Layui 内部请求中会被默认配置覆盖而失效;推荐用 layui.define 封装统一 ajax 模块,自动注入 token、处理 JSON 序列化、支持 FormData、拦截 401 跳转登录,并显式配置 withCredentials 和后端 CORS 响应头。

为什么不能直接改 layui.ajax 或用 $.ajaxSetup
因为 layui.ajax 是封装过的函数,不暴露原型链;$.ajaxSetup 在 Layui 内部请求中基本失效——它会被 Layui 自己的默认配置覆盖,尤其在 table.render、form.on('submit') 等场景下完全不生效。强行用会导致 headers 丢失、contentType 错乱、甚至跨域失败。
推荐做法:用 layui.define 封装自己的模块
这是最干净、可维护性最强的方式,所有业务代码统一走你封装的入口,便于加 loading、错误重试、token 刷新、日志埋点等逻辑。
在 /modules/common.js(路径按 layui.config({ base: '/modules/' }) 配置)中写:
layui.define(['jquery'], function(exports){
var $ = layui.jquery;
var common = {
ajax: function(options) {
var defaults = {
dataType: 'json',
contentType: 'application/json;charset=UTF-8',
headers: {}
};
// 自动注入 token(兼容 localStorage / sessionStorage)
var token = localStorage.getItem('access_token') || sessionStorage.getItem('access_token');
if (token) {
defaults.headers.Authorization = 'Bearer ' + token;
}
// 合并配置
var opts = $.extend(true, {}, defaults, options);
// POST 且 data 是对象时,自动 JSON.stringify
if (opts.type && opts.type.toUpperCase() === 'POST' && typeof opts.data === 'object' && !(opts.data instanceof FormData)) {
opts.data = JSON.stringify(opts.data);
}
return $.ajax(opts);
}
};
exports('common', common);
});
使用时:
layui.use(['common'], function(){
var common = layui.common;
common.ajax({
url: '/api/user',
type: 'GET',
success: function(res) { console.log(res); }
});
});
- 所有请求都走
common.ajax,headers、序列化、token 注入全可控 -
FormData类型不会被误转成 JSON,上传文件不受影响 - 返回值仍是 jqXHR 对象,可链式调用
.done()、.fail()
注意跨域和凭据传递的硬性要求
如果后端是跨域接口且需要带 cookie 或 token,光设 headers 不够,必须显式开启凭据支持:
- 在封装的
ajax函数里补上:xhrFields: { withCredentials: true } - 后端响应头必须包含:
Access-Control-Allow-Origin: https://your-domain.com(不能是*) - 同时要返回:
Access-Control-Allow-Credentials: true
漏掉任意一条,浏览器会静默丢弃响应,控制台只报「CORS error」但无细节。
别忘了拦截 401 并跳转登录
token 过期时后端通常返回 401,这时候该清 token 并跳转登录页——这个逻辑不适合塞进每个 success 回调里,应该统一收口:
common.ajax = function(options) {
// ...前面的配置合并逻辑
return $.ajax(opts).fail(function(xhr) {
if (xhr.status === 401) {
localStorage.removeItem('access_token');
location.href = '/login.html';
return;
}
// 其他错误由调用方自己处理
});
};
这个拦截点容易被忽略:有人只在 table.request 的 done 里判断 code,但 common.ajax 是底层,401 必须在这里截住,否则后续请求全失败,用户卡在白屏。


















