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

如何在Node.js/TS API中转发Python API的二进制流响应?

Node.js转发二进制ZIP包损坏问题解决

问题背景

  • Python API返回包含多份PDF的ZIP包,Content-Type为application/octet-stream,直接通过浏览器/Postman调用可正常下载解压
  • Node.js/TS中间API需要转发该Python API的响应给UI,但下载的ZIP包提示损坏,对比发现响应体字节大小和内容存在差异

原代码

// 调用Python API并转发
const apiResponse = await fetchDoc(Id);

res.setHeader('content-type', apiResponse.headers["content-type"]);
res.setHeader('content-disposition', apiResponse.headers["content-disposition"]);
res.send(apiResponse.result);

async fetchDoc(Id) {
  let response = { error: null, result: null, headers: null };
  const result = await request(options);
  const contentType = result.headers["content-type"];
  if (method === 'GET' && contentType !== "application/octet-stream") {
      logger.info(`GET method result.headers: ${JSON.stringify(result.headers, null, 4)}`);
      response.result = JSON.parse(result.body)
  } else {
      logger.info(`either POST or GET method with octet-stream`);
      response.result = result.body;
  }    
  response.headers = result.headers;
  return response
}

问题原因

request库默认会将响应体转换为UTF-8字符串,而二进制ZIP包包含非UTF-8兼容的字节,转换过程中会导致数据损坏,最终转发的ZIP包无法正常解压。

解决方案

1. 修改request配置,保留二进制Buffer

在request的配置中添加encoding: null,让响应体以Buffer形式返回,避免字符串编码转换:

// 修改request的options配置
const options = {
  // 你的其他请求配置(url、method等)
  encoding: null // 关键:禁用自动编码,返回原始Buffer
};

2. 优化响应转发逻辑

确保转发时直接传递Buffer,同时处理响应头的大小写问题(部分环境下headers键可能为小写):

const apiResponse = await fetchDoc(Id);

// 处理响应头的大小写兼容
const contentType = apiResponse.headers['content-type'] || apiResponse.headers['Content-Type'];
const contentDisposition = apiResponse.headers['content-disposition'] || apiResponse.headers['Content-Disposition'];

res.setHeader('Content-Type', contentType);
res.setHeader('Content-Disposition', contentDisposition);
// 直接发送Buffer类型的响应体
res.send(apiResponse.result);

3. 完整修改后的fetchDoc函数

async fetchDoc(Id) {
  let response = { error: null, result: null, headers: null };
  // 添加encoding: null到options
  const options = {
    // 原有配置
    encoding: null
  };
  const result = await request(options);
  const contentType = result.headers["content-type"];
  if (method === 'GET' && contentType !== "application/octet-stream") {
      logger.info(`GET method result.headers: ${JSON.stringify(result.headers, null, 4)}`);
      // 手动将Buffer转为UTF-8字符串后解析JSON
      response.result = JSON.parse(result.body.toString('utf8'));
  } else {
      logger.info(`either POST or GET method with octet-stream`);
      response.result = result.body; // 此时body是Buffer
  }    
  response.headers = result.headers;
  return response
}

说明

设置encoding: null后,request返回的result.body会是Buffer类型:

  • 对于JSON响应,需要手动调用toString('utf8')转换为字符串后再解析
  • 对于二进制响应(如ZIP),直接返回Buffer即可,转发时Express的res.send会自动处理Buffer的传输

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 15:54:36