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

Node.js AWS Lambda远程PDF上传S3后文件空白问题求助

解决Lambda中下载PDF上传S3后文件空白的问题

我之前也碰到过Lambda里上传PDF到S3后文件空白的问题,大概率是你没处理好二进制数据的获取或者异步流程,给你几个实用的解决方案:

问题根源

  • 二进制数据处理错误:request库默认会把响应体按UTF-8字符串解析,但PDF是二进制文件,直接传字符串会导致数据损坏,最终生成空白文件
  • 异步流程未收尾:Lambda函数如果在下载/上传操作完成前就提前结束,会导致S3只收到空数据

修复方案1:修改request配置,获取二进制Buffer

直接在request请求里添加encoding: null,让它返回原始二进制Buffer,再传给S3:

const request = require('request')
const AWS = require('aws-sdk');
const s3 = new AWS.S3();
const viewUrl = "https://link_to_downloadable_pdf/";

exports.handler = (event, context, callback) => {
  // 关键:设置encoding: null获取二进制Buffer
  request({ url: viewUrl, encoding: null }, (err, response, body) => {
    if (err) {
      console.error('PDF下载失败:', err);
      callback(err);
      return;
    }

    // 先检查响应状态码,确保PDF确实下载成功
    if (response.statusCode !== 200) {
      const error = new Error(`下载失败,状态码:${response.statusCode}`);
      callback(error);
      return;
    }

    const s3Params = {
      Bucket: '你的S3桶名称',
      Key: '上传后的文件名.pdf',
      Body: body, // 这里的body是二进制Buffer
      ContentType: 'application/pdf',
      // 可选:设置下载时的文件名
      ContentDisposition: 'attachment; filename="上传后的文件名.pdf"'
    };

    s3.putObject(s3Params, (err, data) => {
      if (err) {
        console.error('S3上传失败:', err);
        callback(err);
      } else {
        console.log('上传成功:', data);
        callback(null, data);
      }
    });
  });
};

修复方案2:用Async/Await简化异步流程(推荐)

如果觉得回调嵌套太麻烦,可以用request-promise-native(Promise版的request)配合async/await,代码更清晰,也更容易处理异步:

首先在本地安装依赖:

npm install request-promise-native

然后修改Lambda代码:

const request = require('request-promise-native');
const AWS = require('aws-sdk');
const s3 = new AWS.S3();
const viewUrl = "https://link_to_downloadable_pdf/";

exports.handler = async (event) => {
  try {
    // 获取二进制Buffer
    const pdfBuffer = await request({ url: viewUrl, encoding: null });

    const s3Params = {
      Bucket: '你的S3桶名称',
      Key: '上传后的文件名.pdf',
      Body: pdfBuffer,
      ContentType: 'application/pdf'
    };

    // 上传到S3
    await s3.putObject(s3Params).promise();

    return {
      statusCode: 200,
      body: JSON.stringify({ message: 'PDF上传成功' })
    };
  } catch (err) {
    console.error('处理失败:', err);
    return {
      statusCode: 500,
      body: JSON.stringify({ error: err.message })
    };
  }
};

修复方案3:流方式上传(适合大文件)

如果PDF文件很大,用流的方式直接把下载的数据流传给S3,避免把整个文件加载到内存,减少Lambda的内存占用:

const request = require('request');
const AWS = require('aws-sdk');
const s3 = new AWS.S3();
const viewUrl = "https://link_to_downloadable_pdf/";

exports.handler = (event, context, callback) => {
  const s3Params = {
    Bucket: '你的S3桶名称',
    Key: '上传后的文件名.pdf',
    Body: request({ url: viewUrl, encoding: null }), // 直接传请求流
    ContentType: 'application/pdf'
  };

  s3.upload(s3Params, (err, data) => {
    if (err) {
      console.error('S3上传失败:', err);
      callback(err);
    } else {
      console.log('上传成功:', data);
      callback(null, data);
    }
  });
};

额外注意事项

  • 调整Lambda的超时时间:如果PDF比较大,下载+上传可能需要几分钟,记得把Lambda的超时时间设长一点(比如5-10分钟)
  • 检查S3权限:确保Lambda的执行角色有s3:PutObject权限,避免因为权限问题导致上传不完整
  • 验证下载的PDF:可以在代码里打印body.length,确认拿到的Buffer长度不为0,说明确实下载到了数据

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 11:52:49