仅从浏览器使用预签名 URL 上传时出现 AWS S3 CORS 错误

Posted

技术标签:

【中文标题】仅从浏览器使用预签名 URL 上传时出现 AWS S3 CORS 错误【英文标题】:AWS S3 CORS Error on uploading with Presigned URL from Browser only 【发布时间】:2021-12-11 07:44:24 【问题描述】:

我们有:

    具有 CORS 设置的 S3 存储桶
[
    
        "AllowedHeaders": [],
        "AllowedMethods": [
            "GET",
            "POST",
            "HEAD",
            "PUT",
            "DELETE"
        ],
        "AllowedOrigins": [
            "*"
        ],
        "ExposeHeaders": [
            "Authorization"
        ]
    
]
    预签名 POST python 代码
return self._client.generate_presigned_post(
            bucket_name or self._bucket_name,
            str(self._s3_bucket_root / full_path),
            Fields=
                'ACL': 'public-read'
            ,
            Conditions=[
                'ACL': 'public-read'
            ],
            ExpiresIn=ttl or self._default_s3_file_ttl
        )
    反应我们得到错误的部分
                Object.keys(signature).forEach((key) => 
                    formData.append(key, signature[key]);
                )
                formData.append('files', file, file.filename);
                console.log('pureApolloClient.mutate // formData', formData);
                
                axios.post(
                    url,
                    formData,
                    
                        headers: 'Content-Type': 'application/octet-stream'
                    
                );
    Firefox:http://localhost:3000 控制台错误
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://hr-eco-bucket.s3.amazonaws.com/. (Reason: CORS request did not succeed).

大约一个星期后,我无法弄清楚出了什么问题。 CORS 设置为最大访问权限,我应该没有错误

UPD 1:使用预签名 URL 上传与 python 测试完美配合

    signature = uploader.generate_presigned_url(fv.id, submission_uuid, submission_filename)

    resp = requests.post(
        signature['url'],
        data=signature['fields'],
        files='file': (submission_filename, file_content)
    )
    pdb.set_trace()
    assert resp.status_code == 204

    file_resp = requests.get(
        f'https://hr-eco-bucket.s3.eu-central-1.amazonaws.com/client-upload/vacancy/fv.id/submission/submission_uuid/submission_filename'
    )
    assert file_resp.content == file_content

UPD 2:我不确定这些屏幕截图有什么帮助。

【问题讨论】:

"AllowedHeaders": ["*"] - 这行得通吗?另外,请尽快提出问题! :) 同样的结果。根本没有标题 网络选项卡中的实际错误是什么?您能否附上错误的屏幕截图、请求标头以及响应标头? 添加截图 【参考方案1】:

关闭 AWS 并尝试其他云解决方案。 如果存在无法通过文档或指南明确解决的错误,则不应使用该服务。

更新: 告诉它真的很难过,但我已经尝试过 GCP 存储并且它有效。不用头疼,我刚刚设置了 CORS 标头,设置了存储桶策略以及上面的所有代码库和设置,除了 AWS 之外,与 GCP 配合得很好。 我希望这将是另一个答案 - 我无法相信 S3 无法以一种简单的方式与 CORS 一起工作。

【讨论】:

“使用其他平台”如何成为真正的解决方案?预签名上传在 AWS 中工作得很好,但要正确配置就很麻烦了。

以上是关于仅从浏览器使用预签名 URL 上传时出现 AWS S3 CORS 错误的主要内容,如果未能解决你的问题,请参考以下文章

使用预签名 URL 将文件上传到 Amazon S3 时出现 CORS 错误

使用 AlamoFire 和预签名 URL 将图像上传到 S3 存储桶时出现问题

如何将文件上传到 AWS 中的预签名 URL?

PUT 上传文件到 AWS S3 预签名 URL Retrofit2 Android

AWS S3 通过预签名 URL 上传返回 400 错误请求

AWS 预签名 URL