从云功能流式传输zip下载

时间:2019-01-26 18:47:21

标签: node.js firebase express google-cloud-functions

我有一个firebase云功能,该功能使用express将图像的zip文件流传输到客户端。当我在本地测试云功能时,它可以正常工作。当我上传到Firebase时,出现此错误:

  

错误:发送标头后无法设置。

什么可能导致此错误?内存限制?

export const zipFiles = async(name, params, response) => {


  const zip = archiver('zip', {zlib: { level: 9 }});


  const [files] = await storage.bucket(bucketName).getFiles({prefix:`${params.agent}/${params.id}/deliverables`});

  if(files.length){
    response.attachment(`${name}.zip`);
    response.setHeader('Content-Type', 'application/zip');
    response.setHeader('Access-Control-Allow-Origin', '*')

    zip.pipe(output);

    response.on('close', function() { 
      return output.send('OK').end(); // <--this is the line that fails
  });

  files.forEach((file, i) => {

    const reader = storage.bucket(bucketName).file(file.name).createReadStream();
    zip.append(reader, {name: `${name}-${i+1}.jpg`});

  });
  zip.finalize();
}else{
  output.status(404).send('Not Found'); 
}

1 个答案:

答案 0 :(得分:0)

弗兰克在评论中说的是真的。开始发送任何内容正文之前,您需要确定所有标头,包括HTTP状态响应。

如果您要表达自己发送成功的响应,只需以与处理404错误相同的方式说output.status(200)。事先做。当您传递响应时,您无需执行任何操作即可最终关闭响应。管道完成后,响应将自动刷新并完成。仅当您想尽早纾困而根本不发送任何回复时,才应该致电end()

请记住,Cloud Functions仅支持最大10MB的有效负载(read more about limits),因此,如果您尝试压缩的总容量超过该总容量,则将无法使用。实际上,根本没有“流式”响应或分块响应。整个有效负载都内置在内存中,并作为一个单元传输出去。