choose是唯一可靠入口,因layui upload仅在此阶段暴露原始File列表并支持obj.resetFile()替换文件;before无法重置文件,auto模式下修改无效,必须用Promise.all()并发压缩后统一调用obj.upload()。
必须在 choose 回调里做压缩,不能依赖 before 或直接传原始 file 对象——因为 layui 的 upload.render() 在自动上传模式下会跳过你对文件的修改,只有手动调用 obj.upload() 才能确保压缩后的 blob 被真正发送。
为什么 choose 是唯一可靠入口
layui 的 upload 模块在 choose 阶段才暴露原始 File 列表(通过 obj.pushFile()),且此时文件尚未提交;before 阶段虽然也能拿到 file,但无法替换或重置它——obj.resetFile() 只在 choose 中有效。若误用 before,后端收到的仍是未压缩的大图。
-
choose中可调用obj.preview()实时预览 base64 - 必须用
obj.pushFile()获取全部待上传文件,再逐个判断、压缩、替换 - 压缩完成后需显式调用
obj.upload(index, file)发送单个文件,禁用auto: true
photoCompress 函数的关键参数与限制
该函数本质是用 FileReader + canvas 重绘缩放并调用 toDataURL('image/jpeg', quality) 生成压缩 base64,再转为 Blob。它不支持 WebP、不处理 EXIF 朝向、不兼容 IE10 以下。
-
quality推荐设为0.7~0.85:低于0.6明显模糊,高于0.9压缩率低 - 务必检查
file.type是否为image/jpeg或image/png,否则toDataURL('image/jpeg')可能输出空白 - 若原图宽高超 4096px,部分安卓 WebView 会崩溃,建议先等比缩放到
maxWidth: 2000
如何把压缩后的 Blob 正确塞回上传队列
layui 不允许直接修改 files 对象,必须用 obj.resetFile(index, blob, filename) 替换原始项,否则 obj.upload() 仍发原始文件。
-
index来自for (let index in files)循环,不是数组下标,需用Object.keys(files)[i]安全取键 -
filename必须保留原名(含扩展名),否则后端Content-Type可能识别错误 - 压缩失败时,应调用
obj.upload(index, files[index])回退上传原图,避免中断流程
最易被忽略的是:压缩过程异步,而 choose 回调是同步执行的——你必须在所有压缩完成后再统一触发上传,不能在循环里直接 obj.upload(),否则顺序错乱、部分文件丢失。实际项目中建议用 Promise.all() 控制并发压缩,再批量调用 obj.upload()。
















