Node.js Express后端无法向jQuery前端传输Zip文件实现自动下载
问题:Ajax下载adm-zip生成的压缩包为空且损坏
我在服务器端用adm-zip压缩文件,本地生成的压缩包完全正常,但通过前端jQuery Ajax请求下载后,文件为空且损坏。
后端代码(压缩逻辑正常)
const zip = new AdmZip(); zip.addFile(/e/Projects/NodeJs/lknkjnknb/lknkjnknb.pdf); zip.addFile(/e/Projects/NodeJs/lknkjnknb/lknkjnknb2.pdf); zip.writeZip('/Projects/NodeJs/lknkjnknb.zip'); // 本地生成的压缩包正常 const data = zip.toBuffer(); res.set('Content-Type','application/octet-stream'); res.set('Content-Disposition',attachment; filename=lknkjnknb.zip); res.set('Content-Length',data.length); res.send(data);
前端Ajax代码(下载后文件损坏)
$.ajax({ url: url, type: "GET", responseType: 'arraybuffer', success: async function(response){ const url = window.URL.createObjectURL(new Blob([response])); const link = document.createElement('a'); link.href = url; link.setAttribute('download', prj+'.zip'); document.body.appendChild(link); link.click(); }, error: function (error) { console.log(Error ${error}); } });
解决方法
1. 修复前端Ajax的响应类型配置
jQuery的$.ajax不支持直接设置responseType参数,必须通过xhrFields直接配置XMLHttpRequest的属性,才能正确获取二进制数据:
$.ajax({ url: url, type: "GET", xhrFields: { responseType: 'arraybuffer' // 正确设置响应类型为二进制数组 }, success: function(response){ // 创建Blob时指定正确的MIME类型 const blob = new Blob([response], { type: 'application/octet-stream' }); const url = window.URL.createObjectURL(blob); const link = document.createElement('a'); link.href = url; link.setAttribute('download', prj + '.zip'); document.body.appendChild(link); link.click(); // 清理临时URL和DOM元素,避免内存泄漏 window.URL.revokeObjectURL(url); document.body.removeChild(link); }, error: function (error) { console.log(`Error ${error}`); } });
2. 后端代码优化(可选但推荐)
- 修正
addFile的用法:如果是添加本地文件,应该使用addLocalFile方法(addFile用于添加内存中的文件内容),避免参数错误:
const zip = new AdmZip(); // 使用addLocalFile加载本地文件到压缩包 zip.addLocalFile('e/Projects/NodeJs/lknkjnknb/lknkjnknb.pdf'); zip.addLocalFile('e/Projects/NodeJs/lknkjnknb/lknkjnknb2.pdf'); const data = zip.toBuffer(); // 修正Content-Disposition头格式,文件名用双引号包裹 res.set('Content-Type', 'application/octet-stream'); res.set('Content-Disposition', 'attachment; filename="lknkjnknb.zip"'); res.set('Content-Length', data.length); res.send(data);
- 确保
Content-Disposition头的格式正确,文件名用双引号包裹,避免特殊字符导致解析异常。
问题根源
jQuery默认会将响应解析为字符串,手动设置responseType: 'arraybuffer'不会生效,因为jQuery的Ajax封装会覆盖这个配置。通过xhrFields直接设置XMLHttpRequest的响应类型,才能正确获取二进制的arraybuffer数据,否则生成的Blob是错误的字符串转码结果,导致压缩包损坏。
内容的提问来源于stack exchange,提问作者Samarth Srivastava
相关产品推荐
相关产品推荐

