You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Node.js中通过JSON发送PDF文件应采用何种数组格式?

选择PDF在JSON响应中的传输格式:Base64 vs 数字数组

嘿,针对你用Express开发Node.js API、要把AWS上的PDF返回成JSON的场景,我来帮你拆解下几种格式的优劣,结合你的需求给出最适合的方案~

先明确你的核心约束

  • PDF文件不超过200kb,响应大小和速度不是问题
  • 必须返回JSON格式(所以直接返回二进制PDF响应的方案就不考虑了)

可选格式分析

1. Base64字符串(最推荐)

这是JSON中传输二进制数据最常用的方案,优势非常明显:

  • 原生兼容JSON:字符串是JSON的基础类型,不需要任何特殊处理就能序列化/反序列化,后端和前端都不容易出问题
  • 前端处理简单:不管是浏览器还是Node.js前端,都有成熟的方法把Base64转成Blob/Buffer,直接用于显示或保存PDF
  • 可读性尚可:至少是一串可识别的字符,比一堆数字数组更容易调试

唯一的“缺点”是体积会比原二进制大33%左右——但你的PDF最多200kb,转成Base64也就266kb,完全在你的可接受范围内(毕竟你说响应大小速度不是问题)。

后端实现示例(Express + AWS SDK v3)

const { S3Client, GetObjectCommand } = require("@aws-sdk/client-s3");
const express = require('express');
const app = express();

const s3Client = new S3Client({ region: '你的AWS区域' });

// 工具函数:将S3返回的流转成Buffer
const streamToBuffer = (stream) => new Promise((resolve, reject) => {
  const chunks = [];
  stream.on('data', chunk => chunks.push(chunk));
  stream.on('end', () => resolve(Buffer.concat(chunks)));
  stream.on('error', reject);
});

app.get('/api/pdf/:id', async (req, res) => {
  const { id } = req.params;
  try {
    // 从S3获取PDF文件
    const s3Response = await s3Client.send(new GetObjectCommand({
      Bucket: '你的S3桶名',
      Key: `pdfs/${id}.pdf` // 假设PDF在S3中的存储路径
    }));
    
    const pdfBuffer = await streamToBuffer(s3Response.Body);
    // 转成Base64字符串
    const pdfBase64 = pdfBuffer.toString('base64');

    res.json({
      ID: id,
      pdf: pdfBase64
    });
  } catch (err) {
    console.error('获取PDF失败:', err);
    res.status(500).json({ error: 'Failed to retrieve PDF' });
  }
});

app.listen(3000, () => console.log('API服务启动在3000端口'));

前端处理示例(浏览器环境)

async function loadAndOpenPDF(id) {
  const res = await fetch(`/api/pdf/${id}`);
  const data = await res.json();
  
  // 将Base64转成Blob,用于显示或下载
  const pdfBlob = new Blob(
    [Uint8Array.from(atob(data.pdf), c => c.charCodeAt(0))],
    { type: 'application/pdf' }
  );
  
  // 生成临时URL打开PDF
  const pdfUrl = URL.createObjectURL(pdfBlob);
  window.open(pdfUrl);
}

2. Uint8数组/普通数字数组

也就是你示例里的[21, 23, 34, 46, ...]这种格式:

  • 体积和原二进制一致:没有Base64的33%膨胀,但实际上JSON里存储数字数组的字符数可能和Base64差不多(比如一个字节是0-255,转成数字字符串是1-3位,平均下来字符数接近Base64)
  • 前端处理稍繁琐:需要把数字数组重新转成Uint8Array再生成Blob,步骤比Base64多一步

后端实现差异

把转Base64的代码改成:

const pdfArray = Array.from(new Uint8Array(pdfBuffer));
res.json({ ID: id, pdf: pdfArray });

前端处理差异

const pdfBlob = new Blob([new Uint8Array(data.pdf)], { type: 'application/pdf' });

最终推荐

结合你的需求(响应大小速度无压力),优先选择Base64字符串。它的实现成本最低,兼容性最好,前端处理的代码也更通用,不容易踩坑。

如果某天你的PDF体积变大,或者对响应大小有极致要求,再考虑切换到数字数组——但目前完全没必要。

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

火山引擎 最新活动