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

如何用NodeJS+Typescript通过Lambda秒级上传1-2GB文件到S3?

1-2GB文件通过NodeJS+TS Lambda秒级上传S3的最优方案

Lambda天生适合轻量计算,直接处理1-2GB文件上传会受限于执行时间、网络传输效率,完全没必要。最优解是预签名URL方案:Lambda只生成授权的临时上传URL,客户端拿到后直接和S3交互完成上传,Lambda仅做轻量的签名生成操作,执行时间毫秒级,轻松实现秒级响应。

一、Lambda核心实现(NodeJS+TS)

用AWS SDK v3更轻量化,适配Lambda的执行环境:

  1. 安装依赖:
npm install @aws-sdk/client-s3 @aws-sdk/s3-request-presigner
  1. 完整代码:
import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3";
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";

// 初始化S3客户端,Lambda会自动加载执行角色的权限,无需硬编码密钥
const s3Client = new S3Client({ region: "你的S3桶所在区域" });

export const handler = async (event: any) => {
  // 从请求参数中获取文件名、文件类型(如果是API Gateway触发,从event.body解析)
  const { fileName, fileType } = JSON.parse(event.body || "{}");

  // 校验必填参数
  if (!fileName || !fileType) {
    return {
      statusCode: 400,
      body: JSON.stringify({ message: "缺少fileName或fileType参数" }),
    };
  }

  try {
    // 构造S3上传命令
    const putCommand = new PutObjectCommand({
      Bucket: "你的S3桶名称",
      Key: `user-uploads/${fileName}`, // 自定义文件在S3中的存储路径
      ContentType: fileType,
      // 可选:设置文件访问权限,比如公开读
      // ACL: "public-read"
    });

    // 生成预签名URL,有效期设为1小时(可根据业务调整)
    const signedUploadUrl = await getSignedUrl(s3Client, putCommand, { expiresIn: 3600 });

    return {
      statusCode: 200,
      body: JSON.stringify({
        uploadUrl: signedUploadUrl,
        tip: "直接用PUT请求该URL上传文件即可"
      })
    };
  } catch (error) {
    return {
      statusCode: 500,
      body: JSON.stringify({ message: "生成预签名URL失败", error: error.message })
    };
  }
};

二、Lambda权限配置

给Lambda的执行IAM角色添加S3的PutObject权限,示例策略:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "s3:PutObject",
      "Resource": "arn:aws:s3:::你的S3桶名称/user-uploads/*"
    }
  ]
}

三、客户端上传示例(浏览器/NodeJS)

拿到预签名URL后,直接发起PUT请求上传文件:

// 浏览器端示例
async function uploadToS3(uploadUrl, file) {
  const response = await fetch(uploadUrl, {
    method: "PUT",
    body: file,
    headers: {
      "Content-Type": file.type
    }
  });
  return response.ok;
}

// NodeJS端示例
const fs = require("fs");
const axios = require("axios");

async function uploadFromNode(uploadUrl, filePath) {
  const fileStream = fs.createReadStream(filePath);
  const response = await axios.put(uploadUrl, fileStream, {
    headers: {
      "Content-Type": "application/octet-stream" // 根据文件类型调整
    }
  });
  return response.status === 200;
}

四、关键注意事项

  • 文件大小兼容:S3单PUT请求最大支持5GB,完全覆盖1-2GB的需求,不需要分片上传。
  • Lambda资源配置:只需要给Lambda分配128MB内存即可,因为仅做签名生成,内存占用极低,执行时间通常在100ms以内。
  • 安全控制:预签名URL的有效期不要设置太长,建议1小时以内;同时通过IAM角色严格限制Lambda的S3操作范围,避免权限过大。
  • 触发方式:建议用API Gateway触发Lambda,客户端通过HTTP请求获取预签名URL,流程更规范,也方便做身份验证(比如Cognito)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 05:03:19