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

Node.js后端通过axios获取HTTP返回的PDF并正确保存到文件系统的方法

问题原因

你存出来的PDF损坏、打开空白,核心是两个配置错误:

  1. axios默认会把响应内容按UTF-8字符串解析,PDF里包含大量压缩后的非文本二进制字节(就是你看到的那段乱码流),字符串转码过程会直接篡改这些字节的原始值,写出来的文件结构自然就坏了。
  2. Blob是浏览器端的API,Node.js服务端没有适配服务端场景的Blob原生处理逻辑,硬套浏览器端的写法必然出问题。

另外你不用手动解析贴出来的那些PDF结构,%PDF-1.3头、对象块、Widths数组、FlateDecode压缩流都是标准PDF的固有结构,你看到的结构重复本质是字节被转码破坏后,用文本方式查看内容出现的错位,不是接口返回了重复内容。只要保证原始字节一个不差写到本地,PDF阅读器自己就能正常解析。

正确实现方案

核心逻辑只有一个:发请求的时候告诉axios不要做字符串转码,直接返回原始二进制数据,再原封不动写到文件里即可。根据PDF体积选对应写法:

小体积PDF(100MB以内)用ArrayBuffer

const axios = require('axios');
const fs = require('fs/promises');

async function downloadPdf(apiUrl, saveFilePath) {
  const res = await axios.get(apiUrl, {
    responseType: 'arraybuffer', // 最核心配置,缺失必然导致文件损坏
    // 接口需要的鉴权、请求参数正常追加在这里即可
    // headers: { Authorization: 'Bearer xxx' },
    // params: { fileId: 123 }
  });

  // 直接写入二进制缓冲,不要做toString、转Base64、转Blob之类的多余操作
  await fs.writeFile(saveFilePath, res.data);
}

// 调用示例
downloadPdf('你的PDF接口请求地址', './本地存储路径/result.pdf')

大体积PDF用流写入,降低内存占用

如果PDF体积超过100MB,用ArrayBuffer会把整个文件加载到内存占用资源,直接用流的方式边接收边写入:

const axios = require('axios');
const fs = require('fs');
const { pipeline } = require('stream/promises');

async function downloadLargePdf(apiUrl, saveFilePath) {
  const res = await axios.get(apiUrl, {
    responseType: 'stream'
  });
  // 管道自动处理背压、错误捕获,接收完数据自动关闭文件流
  await pipeline(res.data, fs.createWriteStream(saveFilePath));
}
故障排查点

如果按上述写法保存后文件还是打不开,依次检查:

  • 打印响应头的content-type字段,如果不是application/pdf,说明接口返回的根本不是PDF内容,可能是报错的JSON、HTML鉴权页,自然无法作为PDF打开。
  • 不要对拿到的二进制数据做任何编码转换、字符串拼接处理,哪怕你看到内容里包含可读的PDF结构文本,修改编码就会破坏字节完整性。
  • 下载保存场景不需要引入任何第三方PDF解析/处理库,本质就是纯字节拷贝操作,多余的库反而会增加转码损坏的概率。

内容的提问来源于stack exchange,提问作者Kevin Lewis

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 16:27:39