You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AJAX下载生成的Zip文件无法打开问题排查求助

问题分析与解决

你的问题核心是AJAX默认以文本格式处理响应,导致后端返回的Zip二进制数据被错误解析成字符串,字节流损坏,所以下载后的文件无法打开。下面是具体的修复步骤:

前端修改(关键)

需要告诉AJAX请求接收二进制数据,而非默认的文本格式。修改jQuery AJAX代码,添加xhrFields指定响应类型为blob,同时调整回调里的Blob创建逻辑:

$("#btnFileDown").click(function() {
    var obj = $("#grid")
    var ids = obj.getGridParam("selarrrow");
    var params = new Array();
    
    for(var i = 0; i < ids.length; i++) {
        var data = obj.getRowData(ids[i]);
        params.push(data);
    }
    
    $.ajax({
        type: 'POST',
        url : baseUrl + "fileDownload.et",
        data : {data:JSON.stringify(params)},
        // 指定接收二进制Blob数据
        xhrFields: {
            responseType: 'blob'
        },
        success: function(data, textStatus, xhr) {
            let disposition = xhr.getResponseHeader('Content-Disposition'); 
            let filename; 
            if (disposition && disposition.indexOf('attachment') !== -1) { 
                let filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/; 
                let matches = filenameRegex.exec(disposition); 
                if (matches != null && matches[1]) filename = matches[1].replace(/['"]/g, ''); 
            } 
            // 直接使用返回的Blob数据,无需二次包装
            let link = document.createElement('a'); 
            link.href = window.URL.createObjectURL(data); 
            link.download = filename; 
            link.click();
            // 释放URL对象,避免内存泄漏
            window.URL.revokeObjectURL(link.href);
        },
        error: function(jqXHR, textStatus, errorThrown) {
            alert("Failed => " + errorThrown);
        }
    });
});

后端补充优化

后端已能生成正确Zip文件,可补充两个细节避免潜在问题:

  1. 自动关闭输入输出流,释放资源
  2. 设置Content-Length头,让浏览器准确识别文件大小

修改后的后端代码:

@RequestMapping("fileDownload.et")
@Transactional
public void fileDownload(@RequestParam Map<String, Object> param, ModelMap modelMap, HttpServletResponse response) throws ParseException, FileNotFoundException, IOException {

    // After creating ZipFile Code.
    response.setContentType("application/octet-stream");
    response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(zipFile.getName(), "UTF-8"));
    response.setHeader("Content-Transfer-Encoding", "binary");
    // 设置文件长度
    response.setContentLengthLong(zipFile.length());
    
    // try-with-resources 自动关闭流
    try (FileInputStream fin = new FileInputStream(zipFile);
         ServletOutputStream fout = response.getOutputStream()) {
        
        byte b[] = new byte[4096]; // 4KB缓冲区更高效,避免一次性读取大文件
        int leng = 0;
        
        while ((leng = fin.read(b)) > 0) {
            fout.write(b, 0, leng);
        }
        fout.flush(); // 确保所有数据写入响应
    }
}

原代码失效原因

之前的AJAX未指定responseType,jQuery会把后端返回的二进制数据当成UTF-8文本解析,破坏了Zip文件的字节结构(部分字节被转成乱码字符),最终生成的Blob自然损坏,无法正常打开。

内容的提问来源于stack exchange,提问作者King Henry

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 11:10:02