upload.render 的 headers 配置是静态快照,必须在 before 回调中动态设置 this.headers 才能确保每次上传使用最新值,且不可手动设置 Content-Type,业务参数应通过 this.data 传递。
upload.render 的 headers 配置是静态快照,不能靠初始化时写死
很多人以为在 upload.render 里写 headers: { authorization: localstorage.getitem('token') } 就能自动更新,结果 token 刷新后上传仍带旧值甚至 null。这是因为 layui 在 render 执行时就把 headers 对象浅拷贝进内部配置了,后续改 localstorage 或手动赋值 uploadinst.config.headers 都无效——它不监听变更,也不重新读取。
必须在 before 回调里给 this.headers 赋新值
before 是唯一能确保每次上传都用最新 header 的时机。它在文件真正发请求前触发,此时修改 this.headers 会直接影响本次 XHR 实例的请求头。
-
this.headers是当前 upload 实例的上下文对象,直接赋值即可,比如this.headers.Authorization = 'Bearer ' + sessionStorage.getItem('token') - 如果 token 为空或过期,建议
return false主动中断上传,并提示用户登录 - 不要在
choose或done里改this.headers,它们不参与请求头组装 - 若需传业务字段(如
X-Tenant-ID),也得在这儿动态读取并塞进去,不能依赖全局状态
Content-Type 不允许手动设置,否则 multipart/form-data 会被破坏
浏览器上传文件时自动设 Content-Type: multipart/form-data; boundary=...,这是 FormData 正常工作的前提。如果你在 this.headers 里硬写 'Content-Type': 'application/json',后端根本收不到文件,要么解析失败,要么直接 400 拒绝。
- 所有认证类字段(
Authorization、X-Auth-Token)放this.headers - 业务参数(
type、moduleId)统一走this.data,它支持函数返回值,也能在before里动态赋值 - 自定义 header 字段(如
X-Tenant-ID)必须和服务端 CORS 白名单对齐,否则预检请求(OPTIONS)会被浏览器拦截
多次切换 URL 时,headers 必须同步刷新,且不能靠重建实例解决
有人想换地址就调一次 upload.render(),这会导致 DOM 重复绑定、内存泄漏、已选文件丢失。正确做法是只 render 一次,靠 before + obj.upload({ url, headers }) 控制单次请求目标。
- 每次调
obj.upload()都要显式传headers,它不会继承上次的值 - 如果用了
auto: false,那每次手动上传都得重设headers和url - 把 URL 和 headers 映射逻辑抽成函数,比如
getUploadConfig(fileType),避免散落在多个before里
$.ajaxPrefilter 对它完全无效——header 动态注入这件事,必须绑定到 before 生命周期里做,而且得每次上传都执行。











