JSZip使用generateAsync生成文件时如何命名(无需下载)
解决JSZip生成压缩包后添加文件名的问题
我来帮你搞定这个问题——JSZip生成的Blob对象本身确实不带name属性,但我们有两种简单的方式给它补上文件名,完美适配你上传服务器的需求:
方法1:将Blob转换为File对象(推荐)
File是Blob的子类,它天生支持自定义文件名。你只需要在生成Blob后,用File构造函数把它包装一下,就能直接获得带name属性的文件对象:
for (let i = 0, f; f = content[i]; i++) { var zip = new JSZip(); zip.file(f.name, f); zip.generateAsync({ type:"blob", compression:"DEFLATE", compressionOptions: { level: 9 } }) .then(function(content) { // 自定义你的压缩包文件名,比如基于原文件名加.zip后缀 const zipFileName = `${f.name}.zip`; // 把Blob转为File,第三个参数就是文件名 const zipFile = new File([content], zipFileName, { type: content.type }); var item = { 'type' : zipFile.type, 'size' : zipFile.size, 'name' : zipFile.name // 现在name属性就有了! }; // 接下来就可以用这个item或者zipFile直接上传服务器了 }); }
方法2:提前保存文件名(无需转换对象)
如果你不想额外转换File对象,也可以利用let的块级作用域,在循环时提前把要给压缩包的文件名存下来,等异步回调触发时直接使用:
// 把循环变量i改成let,避免var的作用域陷阱 for (let i = 0, f; f = content[i]; i++) { var zip = new JSZip(); zip.file(f.name, f); // 提前定义好压缩包的文件名 const targetZipName = `${f.name}.zip`; zip.generateAsync({ type:"blob", compression:"DEFLATE", compressionOptions: { level: 9 } }) .then(function(content) { var item = { 'type' : content.type, 'size' : content.size, 'name' : targetZipName // 直接用提前保存的文件名 }; // 后续上传逻辑 }); }
重要提醒:
别再用var声明循环变量i了!var是函数级作用域,在异步的then回调里,它会指向循环的最后一次迭代值,导致所有回调都用同一个f。换成let就能解决这个闭包陷阱,确保每个回调都拿到当前循环的正确文件。
内容的提问来源于stack exchange,提问作者Marlon Adarme




