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

使用React JS无法下载MongoDB中二进制存储的PDF文件

问题:PDF上传MongoDB后前端下载失败+无限循环下载

现象说明

  1. 使用express-fileupload将PDF文件上传至MongoDB后,前端下载打开时提示「Error. Failed to load PDF document」
  2. 点击下载按钮会触发无限循环下载的情况

MongoDB存储的数据结构

_id: ObjectId('63b7494295b850d0452a6a81')                                     
username: "sita"                                                                 
email: "sita@gmail.com"                                                            
dob: 2023-01-01T00:00:00.000+00:00                                                
city: "city"                                                                  
address: "add"                                                                   
services: Array                                                                     
0: "Demat"                                                                            
pancard: Object                                                                 
    Data:BinData(0,'JVBERi0xLjcKCjQgMCBvYmoKPDwKL0ZpbHRlciAvRmxhdGVEZWNvZGUKL0xlbmd0aCAzMDEzNQo+PgpzdHJlYW0KeJztvU1247gS…')                                                
    ContentType: "application/pdf"                                                   
createdAt: 2023-01-05T22:03:46.893+00:00                                       
updatedAt: 2023-01-05T22:03:46.893+00:00                                             
__v: 0  

前端React代码

React.useEffect(()=>{
    const fetchClient = async () =>{
        const res = await axios.get('/users/sita@gmail.com');
        setData(res.data.pancard.Data.data);
        setContentType(res.data.pancard.contentType)
    }

   fetchClient()       
},[userdetail]);


const downloadPdf = (filename, contentType) => {
      const file = new Blob([data], { type: contentType });
      saveAs(file, "pancard.pdf") 
      //const fileURL = URL.createObjectURL(file);
      //window.open(fileURL);       
  };

JSX中的按钮调用

<button class="btn btn-primary button" onClick={downloadPdf('pancard', contentType)}>Download</button>

问题修复方案

1. 解决无限循环下载问题

当前按钮的onClick直接执行了downloadPdf()函数,导致组件渲染时就会触发下载,结合useEffect的依赖更新,形成无限循环。

修复代码:
将onClick改为箭头函数,仅在点击时触发下载;同时React中需用className替代class:

<button className="btn btn-primary button" onClick={() => downloadPdf('pancard', contentType)}>Download</button>

2. 解决PDF无法打开问题

MongoDB中存储的BinData是Base64编码的二进制数据,前端直接用返回的字符串创建Blob会导致文件损坏,需要先解码为二进制数组。

修复代码:

第一步:修改数据获取逻辑

React.useEffect(()=>{
    const fetchClient = async () =>{
        const res = await axios.get('/users/sita@gmail.com');
        // 注意MongoDB字段是ContentType(大写C),需与接口返回字段匹配
        setContentType(res.data.pancard.ContentType);
        
        // 解码Base64字符串为Uint8Array二进制数组
        const base64Str = res.data.pancard.Data;
        const binaryStr = atob(base64Str);
        const bytes = new Uint8Array(binaryStr.length);
        for (let i = 0; i < binaryStr.length; i++) {
            bytes[i] = binaryStr.charCodeAt(i);
        }
        setData(bytes);
    }

   fetchClient()       
},[userdetail]);

第二步:完善下载函数(增加空值判断)

const downloadPdf = (filename, contentType) => {
    // 避免数据未加载完成时触发下载
    if (!data || !contentType) return;
    const file = new Blob([data], { type: contentType });
    saveAs(file, `${filename}.pdf`);
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 03:30:42