choose 回调是唯一能做 MD5 校验的时机,因其可访问 File 对象并用 FileReader 分片读取二进制内容,结合 SparkMD5.ArrayBuffer 增量计算,结果挂载到 obj 上供 before 拦截或上传使用。 先明确核心认知:Layui 上传组件中,before 回调无
choose 回调是唯一能做 MD5 校验的时机,因其可访问 File 对象并用 FileReader 分片读取二进制内容,结合 SparkMD5.ArrayBuffer 增量计算,结果挂载到 obj 上供 before 拦截或上传使用。

先明确核心认知:Layui 上传组件中,before 回调无法获取 File 对象,done 和 error 回调则在请求发送之后触发。要防止重复上传,唯一可行的窗口期是文件被选中后、正式上传前。这个窗口恰好落在 choose 回调里。只有 choose 能拿到 obj.files[0],也只有它能够利用 FileReader 分片读取二进制内容。
长期稳定更新的攒劲资源: >>>点此立即查看<<<
具体实现时,存在几个硬性约束:
File.slice() 切块,推荐每块大小为 2 * 1024 * 1024(2MB)。切勿使用 readAsText(file) 全量读取,否则百兆文件会导致 UI 线程卡死。SparkMD5.ArrayBuffer 进行增量添加,每读取一块后执行 spark.append(e.target.result),最后仅调用一次 spark.end()。常见错误是调完 end() 后再次取值,此时返回空字符串——因为 SparkMD5 内部状态已被清空,计算出的值必须立即保存。md5 值手动挂载到 obj 上,例如 obj.md5 = md5Value。这样后续的 before 回调或上传参数中均可直接引用。obj.upload() 之前将 md5 加入表单:obj.upload({data: {fileMd5: md5Value}})。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,更不能实现断点续传。仍然需要在 choose 中独立完成 MD5 计算,并将结果传递给后端,后端据此判断分片去重或秒传。
fileMd5 后,先查询该文件是否已完整上传;若已存在,直接返回成功,跳过所有分片。chunked 自动识别重复文件,它甚至不校验文件名,仅按顺序发送请求。归根结底,真正的难点不在于代码量,而在于分片读取时的内存控制,以及 spark.end() 的调用时机。许多人第一次调用后第二次再去取值时发现为空,正是因为忽略了 SparkMD5 内部状态会被清空——拿到值后立刻存入一个变量,不要等待第二次。
侠游戏发布此文仅为了传递信息,不代表侠游戏网站认同其观点或证实其描述