JSZip结合FileSaver多URL打包导出时Windows端生成空ZIP问题咨询
问题诊断与修复方案
核心逻辑错误
- 计数触发时机完全错误
你代码中的count++是在创建fetch请求、将promise传入zip.file后立刻执行,此时文件内容还没有通过网络请求返回,checkCount判断的只是「所有请求已发起」而非「所有文件内容已加载完成」。不同操作系统的浏览器异步任务调度逻辑、网络响应速度存在差异,macOS下可能刚好请求响应速度快于generateAsync执行时机,内容刚好填充完成,Windows下响应慢就会导致打包时内容为空。 - 文件名存在Windows兼容问题
url.substring(url.lastIndexOf('/'))得到的文件名会携带前置斜杠(比如/test.png),Windows系统不允许文件名中出现斜杠字符,JSZip处理这类非法文件名时会直接忽略对应文件,也会导致最终生成空压缩包。
Blob使用的兼容性说明
标准Blob接口在Windows端主流浏览器(Chrome、Edge、Firefox)中不存在兼容问题,你的问题完全是逻辑错误导致。
修复后代码示例
async function saveToZip(filename, urls) { const zip = new JSZip(); try { // 等待所有文件请求完成后再执行打包 await Promise.all(urls.map(async (url) => { const res = await fetch(url); if (res.status !== 200) { throw new Error(`请求${url}失败: ${res.statusText}`); } const blob = await res.blob(); // 处理文件名,去掉前置斜杠 let name = url.substring(url.lastIndexOf('/') + 1).toLowerCase(); zip.file(name, blob, {binary: true}); })); console.log('All files added to ZIP'); // 所有文件加载完成后再生成压缩包 const blob = await zip.generateAsync({ type: "blob", streamFiles: false }, (metadata) => { console.log(Math.round(metadata.percent) + "%"); }); saveAs(blob, filename); console.log("Finished"); } catch (e) { console.error("打包失败:", e); } }
内容的提问来源于stack exchange,提问作者Tokant
相关产品推荐
相关产品推荐

