使用jQuery-Ajax与SpringBoot下载Zip文件时解压报错求助
问题:SpringBoot + jQuery Ajax下载Zip文件可下载但无法打开
我在使用jQuery/Ajax从SpringBoot应用下载Zip文件时遇到问题:文件能正常触发下载,但打开时提示损坏报错。
后端SpringBoot控制器代码
控制器接收JSON格式POST请求,返回二进制Zip文件字节数组:
@PostMapping(value = "/audit/timetell/generateReports", consumes = APPLICATION_JSON_VALUE, produces = APPLICATION_OCTET_STREAM_VALUE) public ResponseEntity<byte[]> generateTimetellReports(@RequestBody ProjectenWrapper projectenWrapper) throws IOException, SuezException { try { return ResponseEntity .ok() .contentType(APPLICATION_OCTET_STREAM) .body(auditService.generateTimetellReports(projectenWrapper).toByteArray()); } catch (Exception e) { return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null); } }
注:auditService.generateTimetellReports生成的ByteArrayOutputStream已关闭,再转为字节数组返回。
前端jQuery Ajax代码
前端调用接口的代码:
$.ajax({ type: "POST", url: "./generateReports", headers:{"X-CSRF-TOKEN": csrf}, data: JSON.stringify(projectenWrapper), contentType: "application/json", responseType: 'blob', success: function (data) { const fileName = "timetellReports.zip"; var blob = new Blob([data]{type"application/octetstream"}); var isIE = !!document.documentMode; if (isIE) { window.navigator.msSaveBlob(blob, fileName); } else { // 其他浏览器下载代码 } }, // 省略其他配置 });
文件下载后大小与预期一致,但即使让控制器直接返回现有文件的字节数组,打开Zip仍报错,推测问题出在前端代码。
排查与解决方案
1. 修复jQuery的responseType配置问题
jQuery不支持直接在配置中设置responseType: 'blob',该属性属于原生XHR,jQuery会忽略此配置,导致返回的是字符串而非二进制Blob,转成Blob后文件损坏。需要改用xhrFields来设置:
$.ajax({ type: "POST", url: "./generateReports", headers:{"X-CSRF-TOKEN": csrf}, data: JSON.stringify(projectenWrapper), contentType: "application/json", // 改用xhrFields设置responseType xhrFields: { responseType: 'blob' }, success: function (data) { const fileName = "timetellReports.zip"; // 修复Blob构造的语法错误 var blob = new Blob([data], {type: "application/octet-stream"}); var isIE = !!document.documentMode; if (isIE) { window.navigator.msSaveBlob(blob, fileName); } else { // 其他浏览器标准下载实现 const url = window.URL.createObjectURL(blob); const link = document.createElement('a'); link.href = url; link.download = fileName; document.body.appendChild(link); link.click(); // 清理资源 window.URL.revokeObjectURL(url); document.body.removeChild(link); } }, // 错误处理 error: function(xhr, status, error) { console.error('下载失败:', error); } });
2. 修复Blob构造的语法错误
原代码中new Blob([data]{type"application/octetstream"})存在两处语法错误:
[data]和后面的配置对象之间缺少逗号type"application/octetstream"缺少冒号,且MIME类型应为application/octet-stream(带连字符)
正确写法是:new Blob([data], {type: "application/octet-stream"})
3. 验证后端字节数组完整性(可选)
虽然你认为问题在前端,但可以在后端将字节数组写入本地文件,测试是否能正常打开,彻底排除后端生成Zip文件的问题。
内容的提问来源于stack exchange,提问作者Mark SmithAMC
相关产品推荐
相关产品推荐

