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

使用FileReader上传数据大小超出原文件长度的原因排查

问题原因与解决方法

核心问题

  1. readAsBinaryString的缺陷:该方法读取的二进制字符串本质是UTF-8编码的文本,传递给$.ajax时,jQuery会默认对字符串进行编码转换,破坏原始二进制文件的字节结构,导致文件体积变大且损坏。
  2. jQuery默认逻辑不兼容二进制:直接传递字符串形式的二进制数据,jQuery会自动尝试将其转为URL编码格式,进一步篡改数据。

修复方案

方案一:改用ArrayBuffer读取并通过Blob传递

ArrayBuffer能完整保留原始二进制数据,配合Blob传递可避免编码问题:

修改readfile函数:

function readfile() {
    var file = $("#excelFile")[0].files[0];

    var reader = new FileReader();
    reader.addEventListener("load", (event) => {
        // 将ArrayBuffer转为Blob,保留原始文件类型
        const blob = new Blob([event.target.result], { type: file.type });
        restPutPost("post", "rest/mapping", blob, 
        function(data) {
            console.log(`File ${file.name} uploaded.`);
        }, 
        function(xhr, status, error) {
            console.log(`Upload failed: ${error}`);
        }, 
        file.type);
    });

    reader.readAsArrayBuffer(file); // 替换readAsBinaryString
}

同时更新restPutPost函数,添加二进制数据处理逻辑:

function restPutPost(method, url, body, callback = null, errorcallback = null, contenttype = "application/json") {
    let actualbody = body;
    let processData = true;
    
    if (contenttype === "application/json") {
        actualbody = body != null ? JSON.stringify(body) : null;
    } else if (body instanceof Blob || body instanceof FormData) {
        // 二进制数据禁止自动处理
        processData = false;
        // Blob类型自动获取contenttype(如果未传入)
        if (!contenttype && body instanceof Blob) {
            contenttype = body.type;
        }
    }

    $.ajax({
        type: method,
        url: url,
        headers: {
            Accept: "application/json"
        },
        data: actualbody,
        contentType: contenttype || false,
        processData: processData, // 关键配置:禁用数据处理
        success: function (data) {
            callback?.(data);
        },
        error: function (xhr, status, error) {
            errorcallback?.(xhr, xhr.status, error);
        }
    });
}

方案二:直接使用FormData上传(最简便)

FormData是浏览器原生的文件上传对象,自动处理二进制编码,无需手动读取文件:

function readfile() {
    var file = $("#excelFile")[0].files[0];
    const formData = new FormData();
    formData.append("file", file); // "file"需与接口接收的参数名一致

    restPutPost("post", "rest/mapping", formData, 
    function(data) {
        console.log(`File ${file.name} uploaded.`);
    }, 
    function(xhr, status, error) {
        console.log(`Upload failed: ${error}`);
    }, 
    false); // 传入false让浏览器自动设置Content-Type
}

此方案下,前面更新的restPutPost函数已经能正确处理FormData类型。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 12:30:45