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

如何通过Lambda基于S3预签名URL实现跨S3桶文件上传并配置过期特性

问题诊断与修复方案

核心错误点

  • 逻辑错误:生成put_object预签名URL时的Key参数是目标存储桶内的文件存储路径,不能传入源文件的完整HTTP URL,否则会导致目标桶Key非法。且预签名URL仅用于上传授权,不会自动拉取源桶文件,你当前的逻辑缺少「源文件下载→向预签名URL上传」的核心步骤。
  • 代码语法/变量错误:
    1. 缩进不符合Python规范:time.sleep(10)、源桶变量定义等行缩进错误
    2. 变量名不匹配:调用list_objects_v2时使用的桶变量是未定义的bucket_name2,返回值存入response变量后却用未定义的response2取内容
    3. 客户端/参数名不匹配:初始化的S3客户端是s3,生成预签名URL时却调用了未定义的s3_client;目标桶变量定义为destination_bucket_to_send,传参时却用了未定义的destination_bucket

正确实现方案

要实现跨S3桶复制+目标桶文件自动过期,优先推荐方案1,性能更稳定、代码复杂度更低:

方案1:直接使用S3 copy_object接口实现跨桶复制(无需预签名URL)

目标桶的过期特性直接在S3控制台配置生命周期规则即可,不需要在代码中处理,文件复制完成后会自动按规则过期。
修复后代码:

import json
import boto3

s3 = boto3.client('s3')

def lambda_handler(event, context):
    # 源桶配置
    source_bucket = 'mybucketname'
    # 目标桶配置
    destination_bucket = 'my_destination_bucket'
    
    # 获取源桶内最新修改的文件
    response = s3.list_objects_v2(Bucket=source_bucket)
    all_files = response['Contents']        
    latest_file = max(all_files, key=lambda x: x['LastModified'])
    source_file_key = latest_file['Key']
    
    # 直接调用S3原生接口完成跨桶复制
    s3.copy_object(
        Bucket=destination_bucket,
        Key=source_file_key, # 目标桶内的文件路径,可按需自定义
        CopySource={
            'Bucket': source_bucket,
            'Key': source_file_key
        }
    )
    
    return {
        'statusCode': 200,
        'body': json.dumps('文件复制成功')
    }

注意:需要给Lambda执行角色配置源桶的s3:GetObject权限、目标桶的s3:PutObject权限。

方案2:必须使用预签名URL的修复方案

import json
import requests
import boto3

s3 = boto3.client('s3')

def lambda_handler(event, context):
    source_bucket = 'mybucketname'
    destination_bucket = 'my_destination_bucket'
    
    # 获取源桶最新修改的文件
    response = s3.list_objects_v2(Bucket=source_bucket)
    all_files = response['Contents']        
    latest_file = max(all_files, key=lambda x: x['LastModified'])
    source_file_key = latest_file['Key']
    
    # 1. 读取源文件内容
    file_content = s3.get_object(Bucket=source_bucket, Key=source_file_key)['Body'].read()
    
    # 2. 生成目标桶上传预签名URL,Key传目标文件路径
    presigned_url = s3.generate_presigned_url(
        'put_object',
        Params={
            'Bucket': destination_bucket,
            'Key': source_file_key
        },
        ExpiresIn=20000
    )
    
    # 3. 向预签名URL上传文件
    upload_response = requests.put(presigned_url, data=file_content)
    upload_response.raise_for_status()
    
    return {
        'statusCode': 200,
        'body': json.dumps('文件上传成功')
    }

注意:需要提前给Lambda层添加requests依赖,同时配置对应S3权限。

目标桶过期配置说明

直接在目标S3桶的「管理」→「生命周期规则」中创建规则,指定对应前缀的文件过期天数即可,规则会自动生效,无需在代码中额外处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 16:15:02