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

Laravel中为AWS S3预签名URL添加图片格式与大小验证

解决AWS S3预签名URL的图片格式与大小限制问题

你之前的问题核心是错误地将conditions参数直接放在PutObject命令参数中——这个参数属于Post表单上传的策略配置,并不适用于PutObject的预签名请求。要实现你需要的双格式限制和大小校验,以下是两种可行方案:

方案一:PutObject预签名URL(单一格式限制)

如果只需要限制单一图片格式(比如仅JPEG),可以直接在PutObject命令中指定固定的ContentType,客户端上传时必须匹配该值,否则S3会直接拒绝请求。同时添加内容长度范围限制:

// 初始化S3客户端
$client = new S3Client([
    'version' => 'latest',
    'region' => 'ap-south-1',
]);

$bucket = 'bucket_name';
$key = 'target-image-key';
$maxFileSize = 2 * 1024 * 1024; // 2MB换算为字节

// 创建PutObject命令,指定必须匹配的Content-Type
$command = $client->getCommand('PutObject', [
    'Bucket' => $bucket,
    'Key' => $key,
    'ContentType' => 'image/jpeg', // 固定为JPEG格式
]);

// 添加文件大小范围限制
$command->getHandlerList()->appendBuild(function ($command) use ($maxFileSize) {
    $command['@http']['headers']['Content-Length'] = ['range' => [0, $maxFileSize]];
});

// 生成有效期20分钟的预签名URL
$presignedRequest = $client->createPresignedRequest($command, '+20 minutes');

echo (string) $presignedRequest->getUri();

注意:这种方式无法同时支持JPEG和PNG两种格式,因为PutObject预签名URL是绑定单一请求参数的。如果需要多格式支持,推荐使用方案二。

方案二:PostObject预签名表单(多格式+大小限制)

Post表单上传的方式支持更灵活的条件约束,能同时实现多格式校验和大小限制,上传违规文件时S3会直接返回对应错误:

// 初始化S3客户端
$client = new S3Client([
    'version' => 'latest',
    'region' => 'ap-south-1',
]);

$bucket = 'bucket_name';
$uploadPathPrefix = 'user-uploaded-images/'; // 可选:限制上传路径前缀
$maxFileSize = 2 * 1024 * 1024; // 2MB
$expireTime = '+20 minutes';

// 定义上传规则条件
$conditions = [
    ['bucket' => $bucket],
    // 限制文件必须上传到指定路径前缀下
    ['starts-with', '$key', $uploadPathPrefix],
    // 允许JPEG或PNG两种格式
    ['or',
        ['eq', '$Content-Type', 'image/jpeg'],
        ['eq', '$Content-Type', 'image/png']
    ],
    // 限制文件大小在0到2MB之间
    ['content-length-range', 0, $maxFileSize],
    // 可选:设置上传文件的ACL为私有
    ['acl' => 'private']
];

// 生成Post上传的签名表单参数
$postFormParams = $client->createPresignedPost([
    'Bucket' => $bucket,
    'Conditions' => $conditions,
    'Expires' => $expireTime,
    'Fields' => [
        'key' => $uploadPathPrefix.'${filename}' // 保留原始文件名,可自定义Key规则
    ]
]);

// 输出表单参数(前端可直接用这些参数构建上传表单)
echo json_encode($postFormParams);

原代码失效原因

conditions是Post上传策略的专属配置项,PutObject命令并不识别该参数,所以你之前的条件配置完全不会被S3处理。只有通过createPresignedPost方法生成的表单上传参数,才能正确应用这些规则约束。

违规上传的错误反馈

当客户端上传违反规则时,S3会返回明确错误:

  • 上传非JPEG/PNG格式文件:返回403 Forbidden,提示签名不匹配
  • 文件大小超过2MB:返回413 Request Entity Too Large

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 11:27:30