Layui upload 的 done 回调仅识别标准 JSON 响应体,需确保后端返回纯 JSON 字符串且响应头为 application/json;若含 HTML、BOM、空白或错误 Content-Type,则触发 error 而非 done。
layui upload 的 done 回调只认标准 JSON 响应体
如果你上传成功了,但 done 没触发、反而进了 error,大概率是后端返回的不是合法 json,或者 content-type 不对。layui 会用 json.parse() 尝试解析响应体,失败就直接走 error —— 它不关心 http 状态码是不是 200。
常见错误现象:
- 浏览器弹出“文件下载框”(尤其 IE/Edge 旧版)
-
done完全不执行,error被调用,控制台无报错或只显示 “Invalid JSON” - 服务端明明写了
echo json_encode(['code'=>0, 'msg'=>'ok']),前端还是收不到
必须确保:
- 响应头包含
Content-Type: application/json; charset=utf-8(PHP 中用header('Content-Type: application/json; charset=utf-8');) - 响应体是**纯 JSON 字符串**,不能混入任何 HTML、空白、BOM、调试
var_dump或echo - 不要用
print_r、var_export、die('success')这类输出干扰 JSON 结构
PHP 后端返回示例:避开常见陷阱
以下是最小可运行的 PHP 响应写法(以 ThinkPHP/Laravel/Lumen 等框架外的原生场景为例):
header('Content-Type: application/json; charset=utf-8');
// 必须清空输出缓冲,防止意外前置输出
if (ob_get_level()) ob_end_clean();
// 真实上传逻辑……
$result = [
'code' => 0,
'msg' => '上传成功',
'data' => '/uploads/20260411/abc.jpg'
];
echo json_encode($result, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
关键点:
-
ob_end_clean()能干掉因 BOM、空行、配置输出导致的隐藏字符 -
JSON_UNESCAPED_UNICODE避免中文被转成 \uXXXX -
JSON_UNESCAPED_SLASHES让 URL 路径不带多余反斜杠(如"\/uploads\/...")
done 回调里取不到 res.data?检查字段名是否和服务端一致
Layui 不强制要求返回字段叫 data,它只是把整个响应体当对象传进来。如果你后端返回的是 {"url":"/xxx.jpg"},那前端就要写 res.url,而不是想当然用 res.data。
典型误用场景:
- 后端返回
{"file_path":"/xxx.jpg"},前端却写$("#cover").attr("src", res.data)→ 报错Cannot read property 'data' of undefined - 后端用了驼峰(
filePath),前端按蛇形(res.file_path)访问 →undefined
建议做法:
- 在
done里先console.log(res),确认结构再取值 - 加一层存在性判断:
if (res && res.url) { ... },避免脚本报错中断后续逻辑
上传成功后跳转或更新 DOM,别漏掉异步上下文
done 是异步回调,里面的 this 指向不是你期望的 Vue 实例或 jQuery 对象。如果用 jQuery 绑定按钮并依赖 $(this) 更新状态,得提前缓存:
var $btn = $('#uploadBtn');
upload.render({
elem: $btn[0],
url: '/upload',
done: function(res){
// ✅ 正确:用外部变量
$btn.text('上传完成').addClass('layui-btn-disabled');
// ❌ 错误:this 指向 upload 实例,不是 DOM 元素
$(this).text('不会生效');
}
});
容易被忽略的地方:
- 多个 upload 实例共用同一个按钮时,
elem传错 DOM 引用会导致回调绑定错位 - 在
done里操作 DOM 前没等 layer.msg 动画结束,可能被遮盖或闪烁 - 上传图片后要预览,但
res.data是相对路径,没拼上域名或 CDN 前缀,导致 404


















