使用zip.js创建ZIP包功能正常,Firefox110.0.1控制台抛类型错误如何解决?
使用zip.js创建ZIP包时Firefox报流关闭错误的问题
问题详情
我用以下代码从多个非空文件生成ZIP压缩包:
const zipWriter = new zip.ZipWriter(new zip.BlobWriter("application/zip"), { bufferedWrite: true }); const filePromises = values.map(file => zipWriter.add(file.name, new zip.BlobReader(file), {})); return Promise.all(filePromises) .then(() => zipWriter.close()) .then(zipBlob => { const archiveDocumentFileUrl = URL.createObjectURL(zipBlob); const anchorElement = document.createElement("a"); anchorElement.href = archiveDocumentFileUrl; anchorElement.download = "archive.zip"; anchorElement.click(); URL.revokeObjectURL(archiveDocumentFileUrl); return Promise.resolve(anchorElement.download); }) .catch(err => console.error(err));
使用zip.js库,因NetBeans 17不支持async/await,所以采用Promise链式调用。在Firefox 110中触发了以下错误:
TypeError: Can not close stream after closing or error
错误出现在zip.js源码的这段代码中(即使使用未压缩的完整版本也会出现):
await o.pipeThrough(f).pipeTo(c,{preventAbort:!0});try{await c.close()}catch(e){}
其中c是WritableStream。想明确三个问题:这个错误是否属于预期?怎么消除?我的代码是否存在问题?
问题分析与解决
1. 错误是否属于预期?
这个错误属于zip.js内部的预期异常,源码里已经用try/catch捕获了它,所以不会影响ZIP包生成和下载的核心功能。之所以能在控制台看到,是因为Firefox对WritableStream的状态检测更严格,会输出被内部捕获的异常信息,其他浏览器可能不会显示这类日志。
2. 消除错误的两种方法
- 修改zip.js源码
找到触发错误的那段代码,在调用c.close()前先判断流是否处于可关闭状态,避免重复关闭:await o.pipeThrough(f).pipeTo(c,{preventAbort:!0}); try { // 仅当流未被锁定(未关闭)时执行关闭操作 if (!c.locked) { await c.close(); } } catch(e) {} - 调整代码配置
尝试移除bufferedWrite: true这个配置项,修改ZipWriter的初始化代码:
开启const zipWriter = new zip.ZipWriter(new zip.BlobWriter("application/zip"));bufferedWrite后,库内部流的处理逻辑可能会提前关闭流,导致后续的close()调用触发冲突,移除该配置能规避这个问题。
3. 你的代码是否有问题?
你的代码逻辑完全没问题:先批量添加文件,再关闭ZipWriter,最后处理Blob并触发下载,是符合zip.js使用规范的写法。错误根源来自库内部的流处理逻辑,和你的代码无关。
内容的提问来源于stack exchange,提问作者gouessej
相关产品推荐
相关产品推荐

