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

Django+Ajax点击按钮下载二进制文件返回数据异常问题

解决AJAX下载二进制文件体积异常增大的问题

我之前碰到过一模一样的坑!你现在的问题核心是jQuery AJAX默认会把响应内容当成UTF-8字符串解析,而你的.kdb是二进制文件,里面包含大量非UTF-8兼容的字节,转成字符串再转回二进制的过程中会被错误编码,导致文件体积莫名变大(比如单个字节被拆成多个)。虽然Network面板里的Content-Length显示正确,但前端拿到的已经是被篡改后的内容了。

问题根源

你代码里注释掉了responseType: 'arraybuffer',就算打开这个配置,jQuery的AJAX也没法正确处理——因为它的默认逻辑会强制把响应转换成字符串,直接破坏二进制数据的完整性。

最优解决方案:改用原生XMLHttpRequest处理

原生XHR对二进制数据的支持更直接可靠,能完美避开jQuery的自动解析坑。修改你的按钮点击事件代码如下:

$('#btn_gen').on('click',function(e) {
    console.log("Generate clicked");
    const json = {
        'sessn' : global_sessn,
        'fn' : $('#kdb_sel').val(),
        'xml' : $('#kdb_xml').val()
    };

    // 显示加载弹窗
    $('#loading').modal({backdrop: "static"});

    const xhr = new XMLHttpRequest();
    xhr.open('POST', "ajx_generate");
    xhr.setRequestHeader("X-CSRFToken", '{{ csrf_token }}');
    xhr.setRequestHeader("Content-Type", "application/json");
    // 关键配置:直接把响应处理成Blob对象
    xhr.responseType = 'blob';

    xhr.onload = function() {
        $('#loading').modal('hide');
        if (xhr.status === 200) {
            console.log("fun_succ1 success");
            const blob = xhr.response;
            const a = document.createElement('a');
            const url = (window.URL || window.webkitURL).createObjectURL(blob);
            a.href = url;
            a.download = $('#kdb_sel').val();
            document.body.append(a);
            a.click();
            a.remove();
            window.URL.revokeObjectURL(url);
        } else {
            // 触发失败回调
            fun_fail1();
        }
    };

    xhr.onerror = function() {
        $('#loading').modal('hide');
        fun_fail1();
    };

    xhr.send(JSON.stringify(json));
});

为什么这个方案有效?

  • 原生XHR的responseType: 'blob'会直接把服务器返回的二进制数据封装成Blob对象,全程不做任何字符串转码,完全保留原始字节。
  • 彻底避开了jQuery AJAX的自动解析逻辑,从根源上杜绝了二进制数据被篡改的可能。

可选:如果坚持用jQuery处理

要是你不想换掉jQuery,可以注册一个自定义的dataType转换器,强制让它返回原始二进制数据:

// 先注册binary类型的转换器
$.ajaxSetup({
    converters: {
        '* binary': function(data) {
            return data.response;
        }
    }
});

// 修改请求配置
var req = {
    url: "ajx_generate",
    method: "post",
    processData: false,
    contentType: "application/json", // 这里你之前设为false是错误的,发送JSON需要指定这个类型
    headers: { "X-CSRFToken": '{{ csrf_token }}' },
    data: JSON.stringify(json),
    responseType: 'blob',
    dataType: 'binary'
};

不过相比之下,原生XHR的方案更简洁可靠,不容易踩额外的坑。

修改后测试一下,你会发现下载的文件大小和服务器端的原始文件完全一致了!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 15:22:26