You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

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

火山引擎 最新活动