Dropzone.js 如何在文件上传完成前从数据库获取对应ID?
解决方案
核心思路:调整执行顺序,先获取数据库ID再触发上传,不要在sending事件中才发起ID请求
你遇到的本质问题是异步请求的返回时机晚于同步执行的sending事件逻辑,只要把「请求ID」的步骤提前到上传触发之前就能解决,同时还能满足你上传过程中修改视频名称的需求。
具体实现步骤
- 修改Dropzone基础配置,关闭自动上传,改为手动触发:
Dropzone.options.yourDropzoneElementId = { autoProcessQueue: false, // 关闭自动上传 // 其他你原有配置保留 init: function () { const myDropzone = this; // 后续事件逻辑都写在这里 } }
把yourDropzoneElementId替换为你页面上Dropzone容器的ID。
- 重写
create函数,直接返回Ajax Promise对象,不需要额外写回调:
function create() { return $.ajax({ type: 'post', url: urlroot + 'Videos/id', data: {} }); }
- 监听
addedfile事件请求ID,拿到ID后再触发上传
在Dropzone的init配置内添加如下逻辑,async/await写法兼容性足够的情况下优先用这个:
this.on("addedfile", async function (file) { try { // 请求获取数据库ID const idv = await create(); // 将ID挂载到当前file对象上,后续事件可以直接读取 file.uploadId = idv; // 拿到ID后立即触发当前文件的上传 myDropzone.processFile(file); // 这里直接就可以用拿到的idv渲染预览区的修改名称表单,不需要等上传完成 // 用户修改名称时直接拿这个idv调用后端接口,就能实时修改对应数据库记录 } catch (e) { // 请求ID失败的处理逻辑,比如提示用户、移除当前文件 alert("创建记录失败,请重试"); myDropzone.removeFile(file); } });
如果需要兼容不支持async/await的旧环境,改用then写法即可:
this.on("addedfile", function (file) { const _this = this; create().then(function (idv) { file.uploadId = idv; _this.processFile(file); // 同上,这里直接绑定修改名称的逻辑 }).catch(function () { alert("创建记录失败,请重试"); _this.removeFile(file); }); });
- 修改
sending事件逻辑,直接读取存在file对象上的ID即可:
this.on("sending", function (file, xhr, formData) { formData.append("id", file.uploadId); formData.append("artistas", jQuery("#artistas").val()); });
额外说明
- 多文件上传场景下这个方案也适用,每个文件的ID会独立存储在对应file对象的属性中,不会冲突
- 你之前尝试Promise无效是因为没有把上传触发逻辑放到Promise的成功回调中,依然在同步执行的
sending事件中取值,自然拿不到异步返回的结果
内容的提问来源于stack exchange,提问作者brujita
相关产品推荐
相关产品推荐

