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

CI4使用CodeIgniter S3库上传图片后访问URL报AccessDenied错误如何解决

问题原因

你当前代码中仅在putObject方法里配置了ACL => 'public-read'权限,但实际上传走的是ObjectUploader/MultipartUploader分片上传逻辑,初始化这两个上传类时没有传递公开访问的ACL参数,所以上传后的对象默认继承存储桶的私有权限,直接访问URL就会返回AccessDenied错误。

解决方案

方案1:修改上传代码,上传时指定公开权限

修改objectUploader方法,在初始化ObjectUploader和MultipartUploader时增加ACL、ContentType等配置,修改后的代码如下:

private function objectUploader($sourcePath, $destinationPath){
    $source = fopen($sourcePath, 'rb');
    // 新增上传配置项,指定ACL和文件类型
    $uploadOptions = [
        'ACL' => 'public-read',
        'ContentType' => mime_content_type($sourcePath), // 自动识别正确的图片MIME类型
        'StorageClass' => 'STANDARD'
    ];
    $uploader = new ObjectUploader(
        $this->s3Client,
        $this->bucket,
        $destinationPath,
        $source,
        $uploadOptions // 传入配置
    );
    do {
        try {
            $result = $uploader->upload();
            if ($result["@metadata"]["statusCode"] == '200') {
                $this->data = $result;
                return true;
            }
            return FALSE;
        } catch (MultipartUploadException $e) {
            rewind($source);
            // 分片上传也传入同样的配置
            $uploader = new MultipartUploader($this->s3Client, $source, [
                'state' => $e->getState(),
                'bucket' => $this->bucket,
                'key' => $destinationPath,
                'ACL' => 'public-read',
                'ContentType' => mime_content_type($sourcePath),
                'StorageClass' => 'STANDARD'
            ]);
            $this->log_message($type = 'ERROR', $e->getMessage());
            $this->data = $e->getMessage();
            return FALSE;
        }
    } while (!isset($result));
}

方案2:配置存储桶公共访问策略(可选)

如果整个存储桶都是用来存储需要公开访问的静态资源,可以直接配置存储桶策略,无需每次上传都指定ACL,策略示例如下:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublicReadGetObject",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::你的存储桶名称/*"
        }
    ]
}

注意事项

  1. 操作前先确认S3存储桶的「阻止公共访问」设置中,未禁用公共ACL/公共访问,否则上传时指定public-read会报错。
  2. 不要固定设置ContentType为image,使用mime_content_type自动识别真实的MIME类型,避免浏览器访问图片时直接下载而非展示。

内容的提问来源于stack exchange,提问作者Mahmud Hasan Jion

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.17 06:54:04