如何保存REST响应的octet stream?Unirest保存格式损坏排查
遇到这种Postman正常但自己的代码出问题的情况,大概率是请求/响应的处理细节和Postman不一致导致的。我给你整理几个最值得优先排查的方向:
强制Unirest获取原始二进制数据
Unirest默认会把响应内容当成文本(比如UTF-8编码)来解析,但octet stream是纯二进制数据,一旦被转码就会破坏原始字节结构,这是最常见的坑。你需要在请求里明确设置encoding: null,让Unirest返回原始的Buffer而不是字符串:unirest.get(url) .encoding(null) // 关键配置:禁用自动编码,保留二进制Buffer .end(function(response) { if (response.statusCode === 200) { // 直接写入Buffer,不要转成字符串 fs.writeFile('your-file.ext', response.body, (err) => { if (err) console.error('写入文件失败:', err); }); } });如果之前没加这个配置,Unirest会把二进制数据错误地解析成UTF-8字符串,写入文件时自然会出现编码不匹配的问题。
完全复刻Postman的请求头
Postman发起请求时会带上一系列默认头,比如Accept: */*、特定的User-Agent等,而Unirest的默认请求头可能和它不一样。服务端可能会根据请求头返回不同格式的数据,比如只有收到Accept: application/octet-stream时才返回正确的二进制流。你可以打开Postman的「请求详情」,复制所有请求头,在Unirest里完全照搬:
unirest.get(url) .header('Accept', '*/*') .header('User-Agent', 'PostmanRuntime/7.32.3') .header('Cache-Control', 'no-cache') // 把Postman里的其他请求头都加进来 .encoding(null) .end(...);检查文件写入的方式
确保你是用二进制模式写入文件。在Node.js中,直接传入Buffer给fs.writeFile默认就是二进制模式,但如果不小心把response.body转成了字符串再写入,就会破坏数据。另外,对于大文件,建议用流式写入来避免内存处理的问题:const writeStream = fs.createWriteStream('your-file.ext'); unirest.get(url) .encoding(null) .pipe(writeStream); writeStream.on('finish', () => { console.log('文件写入完成'); });验证数据完整性
对比服务端返回的Content-Length头和实际写入文件的字节数,如果两者不相等,说明数据在传输或处理过程中被截断了。你可以在代码里打印这两个值:unirest.get(url) .encoding(null) .end(function(response) { const expectedSize = parseInt(response.headers['content-length'], 10); const actualSize = response.body.length; console.log(`预期大小: ${expectedSize}, 实际大小: ${actualSize}`); // 如果不一致,检查Unirest是否有响应大小限制、超时设置等 });排查Unirest版本问题
不同版本的Unirest在二进制数据处理上可能存在bug,比如旧版本对Buffer的处理有问题。可以尝试升级到最新版本,或者降级到一个稳定版本,看问题是否消失:npm install unirest@latest
内容的提问来源于stack exchange,提问作者Ulysses

