使用JavaScript+JSZip仅能提取Zip中10张图片,如何获取全部450张?
问题:JSZip解压含450张图片的Zip文件仅能提取10张
我使用JSZip工具解压一个包含450张图片的Zip文件夹,但目前只能提取出10张。以下代码仅能下载10张图片,无法提取全部内容:
function unzipfeb146() { var i = 0; // fetch('file:///C:/CBTOffline/Images/8687.Zip') fetch('http://localIP/CBT/R3Images/QBQuestionImages/8688.zip') .then(response => response.arrayBuffer()) .then(data => { // Extract the files from the zip const zip = new JSZip(); return zip.loadAsync(data); }) .then(zip => { // Download each file Object.keys(zip.files).forEach(filename => { debugger; zip.files[filename].async('blob').then(blob => { const link = document.createElement('a'); link.href = URL.createObjectURL(blob); `your text` link.download = filename; document.body.appendChild(link); link.click(); var img = document.createElement("img"); img.src = URL.createObjectURL(blob); img.id = i + 1; document.body.appendChild(img); i = i + 1; //const image = new Image(); //image.src = URL.createObjectURL(blob); //image.id = fileName; //document.body.appendChild(image); //document.body.removeChild(link); }); }); }) .catch(error => console.error(error)); }
期望效果

问题排查与解决方法
1. 核心原因:浏览器批量下载限制
大部分浏览器会拦截短时间内的高频下载请求,一次性触发450次link.click()会被浏览器判定为恶意请求,仅允许前10次左右的请求通过。
2. 解决思路与优化代码
方案一:重新打包所有图片为Zip后下载(推荐)
避免逐个触发下载,把所有图片收集后重新打包成一个Zip文件,只触发一次下载操作,同时在页面展示所有图片:
function unzipfeb146() { fetch('http://localIP/CBT/R3Images/QBQuestionImages/8688.zip') .then(response => response.arrayBuffer()) .then(data => JSZip.loadAsync(data)) .then(originalZip => { const newZip = new JSZip(); const filePromises = []; let imgIndex = 0; // 遍历文件,跳过文件夹,处理图片 Object.keys(originalZip.files).forEach(filename => { if (!originalZip.files[filename].dir) { filePromises.push( originalZip.files[filename].async('blob') .then(blob => { newZip.file(filename, blob); // 在页面插入图片 const img = document.createElement("img"); img.src = URL.createObjectURL(blob); img.id = ++imgIndex; document.body.appendChild(img); }) ); } }); // 所有图片处理完成后,打包下载 return Promise.all(filePromises).then(() => newZip.generateAsync({type: 'blob'})); }) .then(zipBlob => { const link = document.createElement('a'); link.href = URL.createObjectURL(zipBlob); link.download = 'all_images.zip'; document.body.appendChild(link); link.click(); document.body.removeChild(link); }) .catch(error => console.error(error)); }
方案二:分批延迟下载
如果必须逐个下载图片,可以给下载操作添加延迟,分批触发请求,绕过浏览器限制:
function unzipfeb146() { let imgIndex = 0; fetch('http://localIP/CBT/R3Images/QBQuestionImages/8688.zip') .then(response => response.arrayBuffer()) .then(data => JSZip.loadAsync(data)) .then(zip => { // 过滤掉文件夹,只保留图片文件 const fileList = Object.keys(zip.files).filter(filename => !zip.files[filename].dir); const batchSize = 10; const delay = 500; // 每批间隔500ms // 分批处理下载 for (let batch = 0; batch < Math.ceil(fileList.length / batchSize); batch++) { setTimeout(() => { const start = batch * batchSize; const end = Math.min(start + batchSize, fileList.length); for (let j = start; j < end; j++) { const filename = fileList[j]; zip.files[filename].async('blob').then(blob => { // 下载图片 const link = document.createElement('a'); link.href = URL.createObjectURL(blob); link.download = filename; document.body.appendChild(link); link.click(); document.body.removeChild(link); // 在页面插入图片 const img = document.createElement("img"); img.src = URL.createObjectURL(blob); img.id = ++imgIndex; document.body.appendChild(img); }); } }, batch * delay); } }) .catch(error => console.error(error)); }
3. 前置排查步骤
先确认Zip文件本身的完整性:在then(zip => {})里添加打印,查看文件总数是否为450:
console.log(Object.keys(zip.files).length);
如果数量不足,说明下载的Zip文件损坏,需要先排查网络请求或文件本身的问题。
内容的提问来源于stack exchange,提问作者Niveditha Jalgam
相关产品推荐
相关产品推荐

