done是唯一可靠入口,因layui仅在成功解析标准json且code字段匹配时才触发它并传入已解析对象;若响应结构不符、解析失败或code不匹配,则跳过done直接进error或静默失败。
done 回调是唯一可靠入口,不是 success、complete 或手动解析 xhr.responsetext
为什么 done 才是正确入口
Layui upload 不直接暴露原生 XHR 对象,也不在 error 或 complete 中自动解析响应体。它只在内部成功解析 JSON 且 code 字段符合预期(默认为 0)时,才触发 done 并把已转为 JS 对象的响应数据传入。
- 若服务器返回
{"code":0,"data":{"url":"/upload/a.jpg"}},done的res参数就是这个对象 - 若返回
{"status":200}但没配response.statusName,done根本不会执行 - 即使网络请求是 200,只要 JSON 解析失败或
code !== 0,就会跳过done进error,甚至静默失败
上传后拿不到 res.data?先检查这三处
常见现象是 done 函数执行了,但 res 是空对象或字段缺失。根本原因几乎都落在服务端响应结构或前端配置上:
- 后端返回体必须是纯 JSON 字符串,不能含 BOM、HTML 注释、前后空格或额外换行
- 响应头
Content-Type必须为application/json(IE8 等旧浏览器例外,需设为text/html) - 未显式配置
response映射时,Layui 默认只认code字段;若后端用status或result.code,必须通过response.statusName告诉组件
response 配置怎么写才生效
这个对象不是可有可无的装饰项,而是决定 done 能否拿到数据的关键开关。尤其当后端 API 已固定字段名时,必须靠它桥接:
-
statusName: 'status'—— 告诉 Layui 把res.status当作状态码 -
statusCode: 1—— 指定值为 1 才算成功(默认是 0) -
msgName: 'message'—— 错误提示从res.message取 -
dataName: 'payload'—— 实际业务数据在res.payload下,而非顶层
示例配置:
layui.upload.render({
elem: '#upload',
url: '/api/upload',
response: {
statusName: 'code',
statusCode: 200,
msgName: 'msg',
dataName: 'data'
},
done: function(res) {
console.log(res.data.src); // 正确取到 /upload/xxx.png
}
});
IE8 下 res 是字符串而不是对象?
IE8 不支持 JSON.parse 或对 MIME 类型极其敏感,即使后端返回了标准 JSON,也可能被浏览器当成附件下载或原样传给 done。
- 后端必须返回
String类型(非 JSON 对象),内容为合法 JSON 字符串 - HTTP 响应头强制设为
Content-Type: text/html; charset=utf-8,绕过 IE8 的 JSON 下载逻辑 - 前端无需额外
JSON.parse,Layui 内部会尝试解析;若仍失败,done收到的就是原始字符串,此时需手动处理
最稳妥的做法:无论什么浏览器,都确保后端输出是严格 UTF-8 编码、无 BOM、无空格的 JSON 字符串,并配好 response 映射——这才是跨环境稳定的基线。











