Node.js中如何将外部API返回的PNG数据直接作为API响应返回
Node.js中转外部API的PNG响应直接返回(不存服务器)
我在Node.js中调用某外部API,其响应体为PNG格式数据。目前可通过以下代码将图片保存至服务器:
const writer = fs.createWriteStream("testimage.png"); const streamResponse = await axios({ method: 'GET', responseType: 'stream', url: endPoint + requestRoute, headers: { 'Authorization': 'Bearer ' + _token } }); streamResponse.data.pipe(writer);
但我不想在服务器保存图片,希望直接将从外部API获取的PNG图片作为自身API的响应返回。尝试了两种方式均失败:
尝试1:直接返回响应体
使用request库直接返回response.body,但无效:
Api.getPNGImage = async function (_request, _respsonse) { var options = { method: 'GET', url: endPoint + requestRoute, headers: { 'content-type': 'application/json', 'Authorization': 'Bearer ' + _token } }; request(options, function (error, response) { let image = response.body; _respsonse.send(image) }); }
尝试2:转Base64返回
生成的Base64无效:
let str = "data:" + 'image/png' + ";base64," + Buffer.from(_responses.body).toString('base64');
可行解决方案
方案1:用Axios流式转发(推荐)
利用Axios的流式响应直接pipe到自身API的响应对象,无需保存文件:
Api.getPNGImage = async function (_request, _response) { try { const streamResponse = await axios({ method: 'GET', responseType: 'stream', url: endPoint + requestRoute, headers: { 'Authorization': 'Bearer ' + _token } }); // 设置响应头为PNG格式,让客户端正确识别 _response.setHeader('Content-Type', 'image/png'); // 将外部API的流直接转发给客户端 streamResponse.data.pipe(_response); } catch (error) { _response.status(500).send('获取图片失败'); } };
方案2:修复request库的二进制处理
之前的问题是request默认会把响应转成utf8字符串,破坏了二进制数据,添加encoding: null保留原始Buffer:
Api.getPNGImage = function (_request, _response) { var options = { method: 'GET', url: endPoint + requestRoute, encoding: null, // 关键:不转码,保留二进制Buffer headers: { 'Authorization': 'Bearer ' + _token } }; request(options, function (error, response) { if (error) { return _response.status(500).send('获取图片失败'); } _response.setHeader('Content-Type', 'image/png'); // 直接返回二进制Buffer _response.send(response.body); }); };
(可选)正确生成Base64返回
如果需要返回Base64格式,也要基于原始二进制Buffer处理:
// 基于request库的Base64正确写法 request(options, function (error, response) { if (error) { return _response.status(500).send('获取图片失败'); } const base64Str = `data:image/png;base64,${response.body.toString('base64')}`; _response.setHeader('Content-Type', 'text/plain'); _response.send(base64Str); });
内容的提问来源于stack exchange,提问作者Nikit Panchal
相关产品推荐
相关产品推荐

