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

通过Ajax发送PDF文件出现空白文件问题

解决办法:用JS/jQuery给ASP.NET MVC服务器发PDF(不用多部分表单)

我明白你现在的困境——不能改服务器代码,还得绕过多部分表单,把PDF以二进制字符串的方式发过去,但现在上传后文件是空的。别担心,咱们对着服务器的接收逻辑来调整前端代码就行:

第一步:先把PDF文件读成原始二进制数据

首先得用FileReader把文件读成ArrayBuffer,这样能完整保留PDF的二进制内容,不会乱码:

// 给文件选择框绑定change事件
$('#fileInput').on('change', function(e) {
    const selectedFile = e.target.files[0];
    // 先校验是不是PDF
    if (!selectedFile || selectedFile.type !== 'application/pdf') {
        alert('麻烦选个PDF文件哦');
        return;
    }

    const reader = new FileReader();
    reader.onload = function(event) {
        // 拿到文件的ArrayBuffer原始数据
        const fileBuffer = event.target.result;
        // 调用发送函数
        sendPDFToServer(fileBuffer, selectedFile.name);
    };
    // 以ArrayBuffer格式读取文件
    reader.readAsArrayBuffer(selectedFile);
});

第二步:把二进制数据正确发给服务器

这里的关键是不让jQuery乱处理你的数据,还要设置对请求头。分两种情况,看服务器预期接收的是原始二进制还是二进制字符串:

情况1:服务器接收原始二进制流

如果服务器是直接读请求流的,就这么写:

function sendPDFToServer(fileBuffer, fileName) {
    // 把ArrayBuffer转成Blob,保持PDF的MIME类型
    const pdfBlob = new Blob([fileBuffer], { type: 'application/pdf' });

    $.ajax({
        url: '/Home/Upload', // 换成你自己的上传Action地址
        type: 'POST',
        data: pdfBlob,
        // 绝对不能让jQuery处理数据,否则二进制会被破坏
        processData: false,
        // 设置正确的MIME类型,告诉服务器这是PDF
        contentType: 'application/pdf',
        // 如果服务器需要文件名,用自定义请求头传过去
        headers: {
            'X-File-Name': fileName
        },
        success: function(res) {
            alert('上传成功啦!');
            console.log(res);
        },
        error: function(xhr, status, err) {
            alert('上传失败了:' + err);
            console.error('出错详情:', xhr, status, err);
        }
    });
}

情况2:服务器明确要二进制字符串

如果服务器必须要二进制字符串格式,那得把ArrayBuffer转成二进制字符串,还要设置对应的字符集:

// 先写个转换函数:把ArrayBuffer转成二进制字符串
function bufferToBinaryString(buffer) {
    const uint8Arr = new Uint8Array(buffer);
    let binaryStr = '';
    for (let i = 0; i < uint8Arr.length; i++) {
        binaryStr += String.fromCharCode(uint8Arr[i]);
    }
    return binaryStr;
}

// 发送函数改成这样
function sendPDFToServer(fileBuffer, fileName) {
    const binaryStr = bufferToBinaryString(fileBuffer);

    $.ajax({
        url: '/Home/Upload',
        type: 'POST',
        data: binaryStr,
        processData: false,
        // 关键:用x-user-defined字符集,保证二进制字符串不被转码
        contentType: 'text/plain; charset=x-user-defined',
        headers: {
            'X-File-Name': fileName
        },
        success: function(res) {
            alert('上传成功!');
        },
        error: function(xhr, status, err) {
            alert('上传失败:' + err);
        }
    });
}

几个必须注意的点

  • processData: false:这个一定要加!不然jQuery会自动把你的二进制数据转成URL编码的字符串,直接把文件内容搞坏,上传后就是空白。
  • contentType:必须和服务器预期的类型匹配,乱设的话服务器读不懂内容。
  • 别手动编码:绝对不要自己把二进制数据转成base64(除非服务器明确要),不然服务器接收后解析不出来,文件还是空的。

顺便提下服务器的接收逻辑(供你参考)

虽然你不能改服务器,但可以确认下它的Action是不是这么写的(如果是,上面的代码就完全匹配):

[HttpPost]
public ActionResult Upload()
{
    // 从自定义头拿文件名
    var fileName = Request.Headers["X-File-Name"];
    var savePath = Server.MapPath("~/Uploaded/" + fileName);
    // 直接把请求流写到文件里
    using (var fileStream = new FileStream(savePath, FileMode.Create))
    {
        Request.InputStream.CopyTo(fileStream);
    }
    return Json(new { success = true });
}

按这个写法来,上传后的PDF就不会是空的啦!


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:00:03