choose回调是唯一能做MD5校验的时机,因其可访问File对象并用FileReader分片读取二进制内容,结合SparkMD5.ArrayBuffer增量计算,结果挂载到obj上供before拦截或上传使用。
choose 回调是唯一能做 md5 校验的时机
Layui 的 before 回调拿不到 File 对象,done 和 error 已经发完请求——防重复必须卡在文件选中后、上传前。只有 choose 能访问 obj.files[0],也才能用 FileReader 分片读取二进制内容。
choose 中必须用 File.slice() 切块(推荐 2 <em> 1024 </em> 1024),不能 readAsText(file) 全量读,否则百 MB 文件直接卡死 UI SparkMD5.ArrayBuffer 增量追加,每次 spark.append(e.target.result),最后只调一次 spark.end() —— 多调会返回空字符串 md5 值要手动挂到 obj 上(如 obj.md5 = md5Value),供后续 before 或上传参数中使用 obj.upload() 前把 md5 加入表单:obj.upload({data: {fileMd5: md5Value}})
before 回调里如何利用 MD5 拦截重复上传
before 本身不接触文件内容,但它能拿到你在 choose 中挂载的 obj.md5。此时可发起异步校验,比如查服务端是否已存在该哈希:
Promise,且仅 reject 才拦截:return new Promise((resolve, reject) => { $.get('/api/check-md5', {md5: obj.md5}, res => res.exists ? reject('已存在') : resolve()); }) return $.get(...).then(() => false) —— 这个 false 是 resolve 的值,上传照常进行 return false(要求 Layui ≥ v2.6.8) obj.getChooseFiles() 返回的是 FileList,需先转真数组:Array.from(obj.getChooseFiles())
chunked: true 与 MD5 校验的关系
chunked: true 只负责把文件切片发请求,它不生成也不校验 MD5,更不管断点续传。你仍需在 choose 中独立完成 MD5 计算,并把结果传给后端用于分片去重或秒传判定。
fileMd5 后,先查该文件是否已完整上传;若已存在,直接返回成功,跳过所有分片逻辑 chunked 自动帮你“认出”重复文件,它连文件名都不校验,只管按序发包真正的难点不在代码长度,而在分片读取时的内存控制和 spark.end() 的调用时机。很多人卡在第一次调用后第二次返回空值,却没意识到这是 SparkMD5 内部状态清空导致的——拿到值立刻存变量,别等第二次调用。