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

如何阻止Lambda向客户端返回流式输出?解决PDF上传S3显示问题

问题:流式传输PDF到S3时避免客户端显示PDF内容

我正在将远程PDF流式传输至S3存储桶,但PDF的二进制内容会在客户端显示。请问如何修改以下代码,避免客户端显示该PDF?我已尝试调整pipeline等流式命令,但未达到预期效果。

原代码:

const stream = require('stream');
const pipeline = require('util').promisify(stream.pipeline);
const { S3Client } = require("@aws-sdk/client-s3");
const { Upload } = require("@aws-sdk/lib-storage");

exports.handler = awslambda.streamifyResponse(async (event, responseStream) => {

  const requestStream = new stream.PassThrough();
  const url = 'https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf'

  require('https').get(url, (response) => {

    try {

      response.pipe(requestStream);
      const parallelUploads3 = new Upload({
        client: new S3Client(),
        params: { Bucket: 'my-bucket', Key: 'wow.pdf', Body: requestStream }
      });

      parallelUploads3.done();

    } catch (e) {
      console.log(e);
    }

  });

  responseStream = awslambda.HttpResponseStream.from(responseStream);
  await pipeline(requestStream, responseStream);

});

解决方案

问题根源在于你把同一个requestStream同时传给了S3上传和客户端响应流,导致PDF二进制数据被直接输出到客户端。需要断开这个流向客户端的管道,改为在上传完成后返回普通的响应信息。

修改后的代码:

const stream = require('stream');
const { S3Client } = require("@aws-sdk/client-s3");
const { Upload } = require("@aws-sdk/lib-storage");
const https = require('https');

exports.handler = awslambda.streamifyResponse(async (event, responseStream) => {
  const response = awslambda.HttpResponseStream.from(responseStream);
  
  try {
    const requestStream = new stream.PassThrough();
    const url = 'https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf';

    // 封装HTTP请求为Promise,确保捕获请求错误
    await new Promise((resolve, reject) => {
      https.get(url, (res) => {
        res.pipe(requestStream);
        res.on('end', resolve);
        res.on('error', reject);
      }).on('error', reject);
    });

    // 执行S3并行上传,等待上传完成
    const parallelUploads3 = new Upload({
      client: new S3Client(),
      params: { Bucket: 'my-bucket', Key: 'wow.pdf', Body: requestStream }
    });
    await parallelUploads3.done();

    // 返回成功响应给客户端
    response.writeHead(200, {
      'Content-Type': 'text/plain',
      'Content-Length': Buffer.from('PDF上传完成').length
    });
    response.end('PDF上传完成');
  } catch (e) {
    console.error('上传失败:', e);
    // 返回错误响应
    response.writeHead(500, {
      'Content-Type': 'text/plain',
      'Content-Length': Buffer.from('PDF上传失败').length
    });
    response.end('PDF上传失败');
  }
});

关键修改点:

  • 移除了await pipeline(requestStream, responseStream),不再将PDF流输出到客户端
  • 用Promise封装https.get,确保能正确捕获请求过程中的错误
  • 等待parallelUploads3.done()完成,保证上传操作执行完毕
  • 上传成功/失败时,返回对应的HTTP状态码和文本提示,而非PDF二进制内容
  • 统一了错误处理逻辑,确保异常情况也能返回合理响应

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 21:17:47