Express.js后端如何将PDF二进制数据转换为可查看的PDF文件
Express服务端处理外部PDF二进制流生成可用PDF方案
你拿到的以%PDF-1.5开头的响应确实是PDF文件的原始二进制内容,出现乱码、字符串拼接表现是因为发起请求时默认使用UTF-8字符串格式解析二进制流,导致内容被错误转码,只要在请求阶段指定正确的二进制响应类型,拿到原始Buffer数据即可生成可正常打开的PDF文件。
核心注意点:如果已经拿到了你贴出的乱码字符串格式的响应,这部分内容已经被错误编码,无法直接修复,必须修改请求配置重新拉取原始二进制数据
具体实现方案
1. 基于axios的实现(最常用)
发起请求时必须配置responseType: 'arraybuffer',禁止默认的字符串解析逻辑,拿到响应后可直接写入本地文件,也可透传给前端预览/下载:
const axios = require('axios'); const fs = require('fs/promises'); const express = require('express'); const app = express(); app.get('/fetch-pdf', async (req, res) => { try { const externalPdfRes = await axios.get('替换为你的外部PDF接口地址', { responseType: 'arraybuffer', // 按需添加鉴权等请求头,比如 headers: { Authorization: 'Bearer 你的token' } }); const pdfBuffer = Buffer.from(externalPdfRes.data); // 场景1:保存PDF到服务器本地 await fs.writeFile('./output.pdf', pdfBuffer); // 场景2:直接返回给前端,支持预览/下载 res.setHeader('Content-Type', 'application/pdf'); // inline为浏览器预览模式,改为attachment即可触发文件下载 res.setHeader('Content-Disposition', 'inline; filename="document.pdf"'); res.send(pdfBuffer); } catch (err) { res.status(500).send('PDF拉取处理失败'); } }); app.listen(3000, () => console.log('服务启动在3000端口'));
2. 基于Node原生http/https模块的实现
如果不使用第三方请求库,用原生模块发请求时不要设置响应编码,手动收集所有二进制块拼接成完整Buffer再处理:
const https = require('https'); const fs = require('fs/promises'); const pdfRequest = https.get('替换为你的外部PDF接口地址', (response) => { // 保持二进制格式,禁止默认UTF8解析 response.setEncoding(null); const chunkList = []; response.on('data', (chunk) => chunkList.push(chunk)); response.on('end', async () => { const fullPdfBuffer = Buffer.concat(chunkList); // 写入本地生成PDF await fs.writeFile('./output.pdf', fullPdfBuffer); console.log('PDF文件生成完成'); }); }); pdfRequest.on('error', (err) => console.error('请求外部接口失败', err)); pdfRequest.end();
常见踩坑排查
- 禁止对二进制PDF响应使用
JSON.parse处理,PDF流不是JSON格式 - 如果生成的PDF打开提示损坏,先对比你拿到的Buffer长度和外部接口返回的
Content-Length响应头数值是否一致,长度不一致说明流传输过程中被截断 - 不要尝试对已经转成乱码字符串的响应做转码修复,二进制数据被UTF8解析后会丢失部分字节信息,无法100%还原为正确的PDF内容,必须重新发请求拉取原始Buffer
内容的提问来源于stack exchange,提问作者Oluwaseun Fabiyi
相关产品推荐
相关产品推荐

