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

前端通过AWS Lambda上传图片至S3并同步存信息到DynamoDB流程咨询

前端图片上传→AWS Lambda→S3+DynamoDB 完整实现流程

一、AWS资源配置

1. 创建S3存储桶

  • 登录AWS控制台创建全局唯一命名的S3桶
  • 配置CORS规则(允许前端跨域上传),在桶的「权限」→「跨域资源共享(CORS)」中添加:
[
  {
    "AllowedHeaders": ["*"],
    "AllowedMethods": ["GET", "PUT"],
    "AllowedOrigins": ["*"], // 生产环境替换为你的前端域名
    "ExposeHeaders": []
  }
]
  • 可选开启桶的版本控制,用于图片版本追溯

2. 创建DynamoDB表

  • 新建表,主键设为imageId(字符串类型,可使用S3对象键或UUID作为唯一标识)
  • 可选添加全局二级索引,方便按uploadTime等字段查询

3. 创建IAM角色

  • 新建Lambda类型的IAM角色,附加以下权限策略:
    • AmazonS3ReadOnlyAccess:允许Lambda读取S3对象元数据
    • 自定义DynamoDB策略:仅允许写入目标表(生产环境避免用全权限)
    • AWSLambdaBasicExecutionRole:允许Lambda写入CloudWatch日志用于调试

4. 创建Lambda函数(S3触发型)

  • 选择Node.js 18.x运行时,关联上述IAM角色
  • 配置S3触发器:添加S3触发源,选择目标桶,事件类型选「Put」(仅监听文件上传),可设置前缀/后缀过滤(如仅处理.jpg/.png)

二、Lambda函数代码实现(Node.js)

功能:监听S3上传事件,提取图片元数据并写入DynamoDB

import { DynamoDBClient, PutItemCommand } from "@aws-sdk/client-dynamodb";
import { marshall } from "@aws-sdk/util-dynamodb";

const dynamoDbClient = new DynamoDBClient({ region: "你的AWS区域" });
const TABLE_NAME = "你的DynamoDB表名";

export const handler = async (event) => {
  try {
    // 解析S3事件中的对象信息
    const s3Record = event.Records[0].s3;
    const bucketName = s3Record.bucket.name;
    const objectKey = decodeURIComponent(s3Record.object.key.replace(/\+/g, " "));
    const fileSize = s3Record.object.size;
    const uploadTime = new Date().toISOString();

    // 构造DynamoDB写入项
    const item = {
      imageId: objectKey,
      bucketName,
      objectKey,
      fileSize: fileSize.toString(),
      uploadTime,
      fileType: objectKey.split(".").pop()
    };

    // 写入DynamoDB
    const command = new PutItemCommand({
      TableName: TABLE_NAME,
      Item: marshall(item)
    });

    await dynamoDbClient.send(command);
    console.log(`成功写入DynamoDB: ${objectKey}`);
    return { statusCode: 200, body: "处理完成" };
  } catch (error) {
    console.error("处理失败:", error);
    throw error;
  }
};

注:Lambda控制台可通过「层」或代码包包含AWS SDK v3依赖;在线编辑时可直接导入SDK(AWS已预装核心包)

三、前端上传实现(原生JS示例)

方式1:Lambda生成预签名URL(推荐,直接上传S3减少中转)

1. 新增预签名URL生成Lambda

import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3";
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";

const s3Client = new S3Client({ region: "你的AWS区域" });
const BUCKET_NAME = "你的S3桶名";

export const handler = async (event) => {
  try {
    const { fileName, fileType } = JSON.parse(event.body);
    const objectKey = `uploads/${Date.now()}_${fileName}`; // 自定义存储路径

    // 生成有效期5分钟的预签名URL
    const command = new PutObjectCommand({
      Bucket: BUCKET_NAME,
      Key: objectKey,
      ContentType: fileType
    });
    const signedUrl = await getSignedUrl(s3Client, command, { expiresIn: 300 });

    return {
      statusCode: 200,
      body: JSON.stringify({ signedUrl, objectKey })
    };
  } catch (error) {
    console.error("生成预签名URL失败:", error);
    return { statusCode: 500, body: "生成URL失败" };
  }
};

2. 配置API Gateway

  • 创建REST API,添加POST方法集成上述Lambda
  • 开启CORS,允许前端域名访问

3. 前端上传代码

<input type="file" id="imageUpload" accept="image/*">
<button onclick="uploadImage()">上传图片</button>

<script>
async function uploadImage() {
  const fileInput = document.getElementById('imageUpload');
  const file = fileInput.files[0];
  if (!file) return;

  try {
    // 1. 请求Lambda获取预签名URL
    const urlResponse = await fetch('你的API Gateway URL', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        fileName: file.name,
        fileType: file.type
      })
    });
    const { signedUrl } = await urlResponse.json();

    // 2. 用预签名URL直接上传文件到S3
    const uploadResponse = await fetch(signedUrl, {
      method: 'PUT',
      headers: { 'Content-Type': file.type },
      body: file
    });

    uploadResponse.ok ? alert('上传成功!') : alert('上传失败,请重试');
    // 上传完成后S3自动触发Lambda写入DynamoDB
  } catch (error) {
    console.error('上传出错:', error);
    alert('上传出错');
  }
}
</script>

方式2:API Gateway中转上传(不推荐,限小文件)

若不想用预签名URL,可直接将文件传给API Gateway,由Lambda接收后上传S3并写入DynamoDB,但受API Gateway默认10MB payload限制,仅适合小文件场景。

四、测试与调试

  • 上传图片后检查S3桶是否存在目标文件
  • 查看Lambda的CloudWatch日志,确认DynamoDB写入状态
  • 验证DynamoDB表中是否存在对应图片信息
  • 失败时优先排查CORS配置、IAM权限、Lambda代码逻辑

五、生产环境优化建议

  • 限制S3桶CORS允许域名,避免使用*
  • 最小化IAM角色权限,遵循权限最小化原则
  • 前端添加文件大小、类型校验
  • 配置S3生命周期规则,自动清理过期图片
  • 启用DynamoDB自动扩缩容,应对高并发写入
  • 为Lambda配置错误重试机制,避免数据丢失

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 05:53:27