使用request-promise从REST API下载PDF无法打开的问题排查
排查PDF下载后无法打开的问题
嘿,我来帮你捋捋这个问题!这种下载的PDF打不开的情况,大概率是二进制数据被错误处理或者请求参数和curl不一致导致的,我给你列几个最常见的坑:
1. 响应编码设置错误(最常见!)
request-promise 默认会把响应内容解析成 UTF-8 字符串,但PDF是二进制文件,一旦被转成字符串再写入文件,字节结构就被破坏了——这就是为什么文件大小看似正常,但打开全是空白或者报错。
解决方法很简单:在请求选项里加上 encoding: null,让rp直接返回二进制 Buffer,而不是解析后的字符串。
2. 请求参数和curl不一致
你说只拥有对应的curl命令,那一定要确保rp的请求和curl完全对齐!比如:
- curl里的
-H自定义头(比如Authorization、Cookie),要原封不动放到rp的headers里 - 如果是POST请求,curl的
-d参数要对应rp的form或body(注意Content-Type头也要匹配) - curl里的
--cookie或者会话信息,也要在rp里正确配置(比如用jar: true或者手动设置Cookie头)
如果参数不对,API可能返回的不是PDF,而是错误页面(比如401的HTML、JSON错误信息)——这些内容大小可能也有1-2MB,但本质不是PDF,自然打不开。
3. 文件写入方式错误
拿到Buffer后,写入文件时不要指定文本编码,直接写入即可。比如用 fs.writeFileSync('your.pdf', pdfBuffer),而不是加 'utf8' 或者 'binary'(虽然binary也能工作,但直接写Buffer是最稳妥的)。
举个实际例子(把curl转成rp)
假设你的curl命令是这样的:
curl -H "Authorization: Bearer abc123" -o output.pdf https://api.example.com/get-pdf
对应的rp代码应该是:
const rp = require('request-promise'); const fs = require('fs'); const downloadOptions = { uri: 'https://api.example.com/get-pdf', headers: { 'Authorization': 'Bearer abc123' // 和curl的-H完全一致 }, encoding: null, // 关键!保留二进制数据 }; rp(downloadOptions) .then(pdfBuffer => { fs.writeFileSync('downloaded.pdf', pdfBuffer); console.log('PDF下载完成,应该能正常打开了!'); }) .catch(err => { console.error('下载出错:', err.message); });
额外排查技巧
你提到用编辑器打开了下载的文件,可以看看开头内容:
- 如果开头是
%PDF-1.4这类标识,说明确实拿到了PDF数据,那大概率是编码/写入的问题 - 如果是HTML标签(比如
<html>)或者JSON(比如{"error":"unauthorized"}),那就是请求没通过认证或者参数错误,API返回了错误内容
内容的提问来源于stack exchange,提问作者Ckappo
相关产品推荐
相关产品推荐

