You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Dropzone.js中解压Zip文件并将内容导入上传器

解决Dropzone.js自动解压Zip并导入内部文件的问题

我之前在使用Dropzone.js开发多文件上传器时,遇到了完全一样的需求:希望上传Zip文件时自动解压,把内部文件直接导入Dropzone继续上传,同时复用已有的上传时长统计、服务器端处理逻辑。最开始尝试用zip.js处理解压,虽然能拿到Blob对象,但不知道怎么把这些Blob转换成Dropzone能识别的上传文件,折腾了一阵终于找到了解决方案,分享给大家:

初始尝试(踩坑代码)

最开始我写了这段代码,能成功解压拿到Blob,但卡在了如何将Blob导入Dropzone的环节:

var mediaDropzone = new Dropzone("#media-dropzone", { 
  dictDefaultMessage: "Click or Drop files here to upload", 
  dictInvalidFileType: "You can't upload files of this type.", 
});
Dropzone.options.mediaDropzone = false;
mediaDropzone.options.acceptedFiles = ".csv,.xls,.xlsx,.txt,.zip";
mediaDropzone.on("sending", function(files, xhr, formData){
 if (files.type === "application/zip"){
 console.log(jQuery.type(files));
 unzipBlob(files, function(unzippedBlob) {
 // logs the uncompressed Blob
 console.log(unzippedBlob);
 });
 this.removeFile(files)
 }
 formData.append("fileuuid", files.upload.uuid);
});
mediaDropzone.on("complete", function(files) {
 var _this = this;
 setTimeout(function(){
 var acceptedFiles = _this.getAcceptedFiles();
 var rejectedFiles = _this.getRejectedFiles();
 for(var index = 0; index < acceptedFiles.length; index++) {
 var file = acceptedFiles[index];
 console.log(jQuery.type(file));
 if (file.status == "success") {
 appendContent(file.status, file.name, file.upload.uuid);
 _this.removeFile(file)
 }
 }
 if(acceptedFiles.length != 0) {
 alertify.success('Uploaded ' + acceptedFiles.length + ' files successfully.');
 }
 if(rejectedFiles.length != 0) {
 alertify.error('Error uploading ' + rejectedFiles.length + ' files.');
 }
 }, 2000);
});
});
function unzipBlob(blob, callback) {
 // use a zip.BlobReader object to read zipped data stored into blob variable
 zip.createReader(new zip.BlobReader(blob), function(zipReader) {
 // get entries from the zip file
 zipReader.getEntries(function(entries) {
 // get data from the first file
 console.log(entries.length);
 for(var index = 0; index < entries.length; index++) {
 var file = entries[index];
 file.getData(new zip.BlobWriter("text/plain"), function(data) {
 // close the reader and calls callback function with uncompressed data as parameter
 console.log("DATA::: " + data.data());
 zipReader.close();
 callback(data);
 });
 };
 });
 }, onerror);
}

最终可行方案

后来换成JSZip库,并且搞清楚了核心要点:需要把解压得到的Blob转换成File对象,再通过Dropzone的addFile()方法导入,这样就能自动触发上传流程了。修改后的核心代码如下:

if (files.type === "application/zip"){
 var zip = new JSZip();
 zip.loadAsync( files /* = file blob */)
 .then(function(zip) {
 return jQuery.map(Object.keys(zip.files), function(filename) {
 return zip.files[filename].async('blob').then(function (fileData) {
 // 过滤Mac系统生成的冗余隐藏文件,避免上传无用内容
 if (filename.includes("_MAC")){
 return;
 } else {
 // 将Blob包装成File对象,保留原文件名,让Dropzone识别为合法上传文件
 var bloblextracted = new File([fileData], filename);
 // 调用addFile方法导入文件,自动触发Dropzone的上传流程
 mediaDropzone.addFile(bloblextracted);
 }
 })
 })
 }, function() {alert("Not a valid zip file")});
 // 移除原Zip文件,防止重复上传
 this.removeFile(files);
 return;
}

关键细节说明

  • 使用JSZip.loadAsync()异步加载Zip文件,不会阻塞页面交互
  • 必须把Blob转换为File对象,因为Dropzone的addFile()方法仅接受File类型参数
  • addFile()会自动触发Dropzone的上传流程,完美复用你之前写的上传逻辑
  • 添加了对Mac系统_MACOSX相关文件的过滤,避免上传无用的隐藏文件

内容的提问来源于stack exchange,提问作者joe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 08:53:11