[AWS-S3] POST 上的预签名 URL 被 CORS 阻止,尽管 CORS 配置启用它

Posted

技术标签:

【中文标题】[AWS-S3] POST 上的预签名 URL 被 CORS 阻止,尽管 CORS 配置启用它【英文标题】:[AWS-S3]POST on presigned URL blocked by CORS despite CORS configuration enabling it 【发布时间】:2021-05-03 11:26:51 【问题描述】:

我正在尝试在 AWS S3 上上传一些媒体

我有 2 个应用程序:

可以通过AWS SDK直接访问S3的后端 需要将一些文件直接上传到 S3 的前端

事情是这样的:

    前端向后端询问 Presigned Post url

    后端调用 S3 API 以获取 URL 和一些字段(Key、Policy 等)

    前端从后端获取这些 URL 并尝试使用适当的表单数据对其请求进行 POST

    我收到此错误:

    https://mydomain.or has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

这是我的 CORS 配置:

[
    
        "AllowedHeaders": [
            "*"
        ],
        "AllowedMethods": [
            "GET",
            "PUT",
            "POST",
            "DELETE"
        ],
        "AllowedOrigins": [
            "https://mydomain.or",
        ]
    
]

这是我的预签名 POST 的后端代码:

    this.videoService.presignedPost(this.entity).toPromise().then((uploadData) =>  //Where I get my URL and fields

        this.fileInput.url = uploadData.url;

        for (const [key, value] of Object.entries(uploadData.fields)) 
            event.formData.append(key, value)
        

        this.fileInput.upload();

     );

这是我的预签名 POST 的后端代码:

 createPreSignedPost(entityDb) 
        let today = new Date();
        console.log(entityDb)
        return new Promise((resolve, reject) => 
            var params = 
                Bucket: BUCKET_NAME,
                Fields: 
                    key: my/key/,
                    success_action_status: '201',
                    signature_expiration: (new Date(today.getTime() + 15 * 60000))
                
            ;


     s3.createPresignedPost(params, function (err, data) 
                if (err) 
                    console.error('Presigning post data encountered an error', err);
                    reject(err)
                 else 
                    console.log('The post data is', data);
                    resolve(url: data.url, fields: data.fields)
                
            );

我尝试了什么:

请求似乎通过 Postman 传递,但存储桶中没有出现任何内容 尝试了与 Chrome 不安全(未集成 CORS 检查)相同的方法 显示 CORS 策略并尝试使用 curl 查看发生了什么

CORS 配置正常,当我使用 curl 检查时,即使我的 CORS 配置中允许方法和主机,我也会被阻止。

我错过了什么吗?

编辑

所以我检查了被 CORS 阻止的请求,并在 HTTP 客户端中使用了完全相同的表单数据、标头等。它适用于客户端,但我的应用仍然被阻止。

【问题讨论】:

如果您删除 CORS 配置,您的 JS 代码是否工作。这将告诉我们问题是您使用的 CORS 还是 JS 设置。 如果我在我的 CORS 配置中启用所有 ORIGINS(我显然想避免这种情况),我会得到一个 net:CONNECTION_ABORTED。 我有same issue,不明白为什么我没有尝试任何工作。 【参考方案1】:

可能什么都没有,但您在“AllowedOrigins”之后有一个无效的逗号:[“https://mydomain.or”,]。这在控制台的 S3 存储桶的 CORS 字段中被标记为无效 JSON。

【讨论】:

哦,抱歉,实际上我在写问题时添加了这个逗号,它不在我的 CORS 配置中:/【参考方案2】:

我确信它与以下任何一种有关:

    您的 JS 设置不正确。 正如其他答案中所建议的,您的 CORS 配置不正确。

我尝试了这个确切的用例(在我的示例中没有 CORS)并且它运行良好。为了测试这个用例,我执行了生成预签名 URL 的 Java V2 示例。请参阅此代码示例:

https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/javav2/example_code/s3/src/main/java/com/example/s3/GeneratePresignedUrlAndUploadObject.java

接下来,我获取了从这个示例生成的 URL,并使用它从另一个应用程序(通常不允许上传)发布数据。

响应为 200:

查看 Java 示例并确保您已在 JS 代码中设置了所有设置。

【讨论】:

您好,感谢您的详细回答,我检查了应用程序发送的所有参数和表单数据,从 HTTP 客户端可以正常工作,但仍然不能从应用程序(我使用的请求与由我的应用程序发送并在 S3 上禁用 CORS)。我仍然无法从我的应用程序上传任何内容,我得到 net:CONNECTION_ABORTED。我还在努力!

以上是关于[AWS-S3] POST 上的预签名 URL 被 CORS 阻止,尽管 CORS 配置启用它的主要内容,如果未能解决你的问题,请参考以下文章

整个存储桶的预签名 url

尝试将图像发送到 React Native 中的预签名 URL 时出现网络错误

NS-Vue/Rails 对 S3 存储桶的预签名 PUT 请求给出 403

iOS 应用签名期间的预填充分发清单信息

AWS S3 存储桶预签名 URL

关于AWS-S3-Bucket-Console-Web控制页面上的Creation date与命令行-API方式如何获取到真正的CreationDate