Node.js调用REST API获取PNG图片无法正常保存的问题
问题描述
调用Node.js获取远程REST API返回的PNG图片,保存后无法打开,系统提示:
The file “***.png” could not be opened.
It may be damaged or use a file format that Preview doesn’t recognize.
相同API在Postman中可正常调用并保存可用图片,但尝试binary、utf8、base64、ASCII编码及fs.createWriteStream写入均无效,返回的原始数据片段如下:
'�PNG ��� IHDR��(������-��biCCPICC Profile��(�m��K�`Ɵh��g)B� T�6�ɡVP�!��[��i!�/ID � �_�RG��UpE�Ypt�h��6jZ�����p�{�!�1=��l�ffa.��� � �A@DDV,���ej�wm������p�o�z����g�×7��ۢ;�Z
解决方案
核心问题是请求时未正确指定响应类型,导致二进制数据被错误编码为字符串,丢失原始字节信息。以下是不同HTTP库的正确实现方式:
1. 使用 axios
设置responseType: 'arraybuffer'直接获取Buffer数据:
const axios = require('axios'); const fs = require('fs'); axios.get('你的API地址', { responseType: 'arraybuffer' // 关键:指定响应为二进制数组 }) .then(response => { fs.writeFileSync('output.png', response.data); console.log('图片保存成功'); }) .catch(err => console.error(err));
2. 使用原生 http/https 模块
通过管道直接传输二进制流,避免编码转换:
const https = require('https'); const fs = require('fs'); const stream = fs.createWriteStream('output.png'); https.get('你的API地址', (res) => { res.pipe(stream); stream.on('finish', () => { stream.close(); console.log('图片保存成功'); }); }).on('error', (err) => { fs.unlink('output.png'); console.error(err); });
3. 使用 node-fetch
通过res.buffer()获取原始Buffer:
const fetch = require('node-fetch'); const fs = require('fs'); fetch('你的API地址', { headers: { /* 与Postman一致的请求头,如Authorization、Accept等 */ } }) .then(res => res.buffer()) .then(buffer => fs.writeFileSync('output.png', buffer)) .catch(err => console.error(err));
关键注意事项
- 确保请求头与Postman完全一致,部分API会根据请求头返回不同格式的数据
- 不要手动对Buffer进行编码转换(如
toString('base64')再转回),直接写入原始Buffer - 使用管道传输时,Node.js会自动保留二进制数据,无需额外处理编码
内容的提问来源于stack exchange,提问作者zhixie
相关产品推荐
相关产品推荐

