Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/amazon-web-services/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js API网关返回损坏的excel文件_Node.js_Amazon Web Services_Express_Aws Lambda_Aws Api Gateway - Fatal编程技术网

Node.js API网关返回损坏的excel文件

Node.js API网关返回损坏的excel文件,node.js,amazon-web-services,express,aws-lambda,aws-api-gateway,Node.js,Amazon Web Services,Express,Aws Lambda,Aws Api Gateway,我的API端点返回一个从S3流式传输的excel文件。它在本地工作,但在API网关上测试时,文件已损坏。以下是我的API代码: const downloadContentFromS3 = async function(bucket, file) { return new Promise((resolve, reject) => { streamFileFromS3(bucket, file, (error, s3buffer) => { if (error)

我的API端点返回一个从S3流式传输的excel文件。它在本地工作,但在API网关上测试时,文件已损坏。以下是我的API代码:

const downloadContentFromS3 = async function(bucket, file) {
  return new Promise((resolve, reject) => {
    streamFileFromS3(bucket, file, (error, s3buffer) => {
      if (error) return reject(error);
      return resolve(s3buffer);
    });
  });
};

const streamFileFromS3 = async function(bucket, fileName, callback) {
  const params = {
    Bucket: bucket,
    Key: fileName,
  };

  const buffers = [];
  const stream = s3.getObject(params).createReadStream();
  stream.on('data', data => buffers.push(data));
  stream.on('end', () => callback(null, Buffer.concat(buffers)));
  stream.on('error', error => callback(error));
};

downloadExcelFile: async (req, res) => {
  try {
    const fileName = 'myFilename';
    const workbook = await downloadContentFromS3(
      'bucket-name'        
      fileName
    );
    const workbook = xlsx.read(buffer);

    res.setHeader('Content-disposition', `attachment; filename=${fileName}`);
    res.setHeader(
      'Content-type',
      'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
    );
    const wbout = xlsx.write(workbook, { bookType: 'xlsx', type: 'buffer' });
    res.status(200).send(Buffer.from(wbout));
  } catch (error) {
    throw new OriolaError(error.message);
  }
},
到目前为止我尝试的内容:设置二进制媒体类型,如图所示:

此外,尝试将响应标题设置为内容类型和内容处置,但没有效果。这个问题似乎一直存在。任何想法和帮助都将不胜感激


编辑:我还尝试在设置中设置二进制类型
*/*
,但这也没有帮助

API网关和Lambda在它们之间作为base64发送文件。这与是否在API网关上设置二进制媒体类型无关,因为API网关在base64和二进制之间进行转换

S3 getObject获得一个二进制文件,但这对于您的问题来说是一个没有实际意义的问题,因为您仍然在使用xlsx创建一个二进制文件

您当前正在做的是将未经转换的二进制数据作为base64数据发送

您所需要做的就是将文件作为base64缓冲区而不是二进制缓冲区返回

所以

变成

res.status(200).send(Buffer.from(wbout).toString('base64'));

所以

  • 设置
    传递行为
    并从函数中发送二进制响应体,就像您已经在做的那样
  • 或者将
    IntegrationResponse资源的
    contentHandling
    属性设置为
    CONVERT\u to\u BINARY
    ,以及已完成的
    binaryMediaTypes
    设置,然后发送
    base64
    响应正文

base64怎么样?也许它是用base64编码下载的?我怎样才能使它正确呢?提供可以实现此目的的标题选项。这对我仍然不起作用。我已经启用了passthrough,我正在发送缓冲区,但它仍然被破坏
res.status(200).send(Buffer.from(wbout).toString('base64'));