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

React/Node.js中基于Buffer数组实现文件创建、展示与下载

Buffer格式附件预览与下载实现方案

你拿到的{type: "Buffer", data: [字节数组]}是Node.js Buffer执行JSON序列化后的标准结构,data字段存储的是文件二进制内容的字节码,不管是React前端直接处理,还是Node.js服务端做流转发,核心都是先把这个字节数组还原为可操作的二进制对象,再实现预览、下载逻辑。


React 前端侧实现(无需服务端中转)

核心依赖:浏览器原生Blob API + URL对象

  • 第一步:将Buffer JSON结构转为Blob对象
    首先把字节数组转为Uint8Array,再结合文件对应的MIME类型生成Blob实例。示例数据开头字节为137,80,78,71,是PNG图片的标准文件头,对应MIME为image/png,其他常见格式对应MIME:PDF为application/pdf、docx为application/vnd.openxmlformats-officedocument.wordprocessingml.document、xlsx为application/vnd.openxmlformats-officedocument.spreadsheetml.sheet。

    /**
     * 把Buffer JSON转成浏览器可识别的Blob
     * @param {Object} bufferJson 接口返回的Buffer结构数据
     * @param {string} mimeType 文件MIME类型
     * @returns {Blob}
     */
    const convertBufferToBlob = (bufferJson, mimeType) => {
      const uint8Arr = new Uint8Array(bufferJson.data);
      return new Blob([uint8Arr], { type: mimeType });
    };
    
  • 第二步:实现文件预览
    用URL.createObjectURL()基于Blob生成本地临时访问地址,直接绑定到对应预览组件即可:图片类直接给<img>标签的src属性,PDF可以嵌入<iframe>,复杂格式可以搭配对应生态组件(比如react-pdf预览PDF、mammoth预览docx)。

    import { useState, useEffect } from 'react';
    
    function AttachmentPreview({ bufferData, mimeType }) {
      const [previewSrc, setPreviewSrc] = useState('');
    
      useEffect(() => {
        const blob = convertBufferToBlob(bufferData, mimeType);
        const objectUrl = URL.createObjectURL(blob);
        setPreviewSrc(objectUrl);
        // 组件卸载时释放临时地址,避免内存泄漏
        return () => URL.revokeObjectURL(objectUrl);
      }, [bufferData, mimeType]);
    
      // 以PNG图片预览为例,其他格式替换对应渲染标签即可
      return <img src={previewSrc} alt="附件预览" style={{ maxWidth: '100%' }} />;
    }
    
  • 第三步:实现文件下载
    同样基于Blob生成临时地址,动态创建a标签触发浏览器下载行为,下载完成后释放临时内存:

    /**
     * 触发文件下载
     * @param {Object} bufferJson Buffer结构数据
     * @param {string} mimeType 文件MIME
     * @param {string} fileName 下载保存的文件名
     */
    const triggerDownload = (bufferJson, mimeType, fileName) => {
      const blob = convertBufferToBlob(bufferJson, mimeType);
      const objectUrl = URL.createObjectURL(blob);
      const aTag = document.createElement('a');
      aTag.href = objectUrl;
      aTag.download = fileName;
      document.body.appendChild(aTag);
      aTag.click();
      document.body.removeChild(aTag);
      URL.revokeObjectURL(objectUrl);
    };
    
    // 调用示例:<button onClick={() => triggerDownload(bufferData, 'image/png', '测试图片.png')}>下载附件</button>
    

Node.js 服务端实现(流转发模式)

如果需要在服务层统一处理文件返回,直接把Buffer JSON还原为原生Buffer对象后,通过响应流返回给前端即可:

  • 第一步:还原Node原生Buffer实例,直接调用Buffer.from()传入字节数组即可,无需额外依赖
    // bufferJson为拿到的{type:"Buffer", data:[...]}结构
    const fileBuffer = Buffer.from(bufferJson.data);
    
  • 第二步:配置响应头返回文件流,以Express框架为例:
    const express = require('express');
    const app = express();
    
    app.get('/api/file/download', (req, res) => {
      // 实际场景从数据库/其他服务拿到Buffer JSON结构
      const bufferJson = { type: "Buffer", data: [137,80,78,71,13,10,26] };
      const fileBuffer = Buffer.from(bufferJson.data);
      const mimeType = 'image/png';
      const fileName = '测试图片.png';
    
      // 设置响应类型
      res.setHeader('Content-Type', mimeType);
      // 配置为下载模式:Content-Disposition设为attachment;需要浏览器直接预览则设为inline
      res.setHeader(
        'Content-Disposition',
        `attachment; filename*=UTF-8''${encodeURIComponent(fileName)}`
      );
      // 直接返回Buffer内容
      res.send(fileBuffer);
    });
    
    app.listen(3000);
    

注意事项

  • 前端生成的Object URL必须在不需要时调用URL.revokeObjectURL()释放,大文件场景下如果不释放会造成明显的内存占用问题
  • MIME类型必须和文件实际格式匹配,否则会出现预览失败、下载后文件无法打开的问题,可以通过文件头魔数自动识别格式,避免硬编码错误
  • 中文文件名在服务端响应时必须做UTF-8编码处理,否则会出现文件名乱码

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 20:39:30