1

我的 S3 存储桶上有一些 CORS 规则。

这是它的样子:

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <CORSRule>
        <AllowedOrigin>https://prod-myapp.herokuapp.com/</AllowedOrigin>
        <AllowedMethod>POST</AllowedMethod>
        <AllowedHeader>*</AllowedHeader>
    </CORSRule>
    <CORSRule>
        <AllowedOrigin>http://prod-myapp.herokuapp.com/</AllowedOrigin>
        <AllowedMethod>POST</AllowedMethod>
        <AllowedHeader>*</AllowedHeader>
    </CORSRule>
</CORSConfiguration>

当我在我的应用程序中,并尝试在我的 JS 控制台中上传文件(又名...执行 POST 请求)时,我收到此错误:

XMLHttpRequest cannot load https://myapp.s3.amazonaws.com/. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://prod-myapp.herokuapp.com' is therefore not allowed access. The response had HTTP status code 403.

我试图从我的 CLI 做一个 POST,我得到了这个:

$ curl -v -H "Origin: http://prod-myapp.herokuapp.com" -X POST https://myapp.s3.amazonaws.com
* Rebuilt URL to: https://myapp.s3.amazonaws.com/
*   Trying XX.XXX.XX.153...
* Connected to myapp.s3.amazonaws.com (XX.XXX.XX.153) port 443 (#0)
* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
* Server certificate: *.s3.amazonaws.com
* Server certificate: VeriSign Class 3 Secure Server CA - G3
* Server certificate: VeriSign Class 3 Public Primary Certification Authority - G5
> POST / HTTP/1.1
> Host: myapp.s3.amazonaws.com
> User-Agent: curl/7.43.0
> Accept: */*
> Origin: http://prod-myapp.herokuapp.com
> 
< HTTP/1.1 412 Precondition Failed
< x-amz-request-id: SOME_ID
< x-amz-id-2: SOME_ID_2
< Content-Type: application/xml
< Transfer-Encoding: chunked
< Date: Thu, 17 Sep 2015 04:43:28 GMT
< Server: AmazonS3
< 
<?xml version="1.0" encoding="UTF-8"?>
* Connection #0 to host myapp.s3.amazonaws.com left intact
<Error><Code>PreconditionFailed</Code><Message>At least one of the pre-conditions you specified did not hold</Message><Condition>Bucket POST must be of the enclosure-type multipart/form-data</Condition><RequestId>SOME_ID</RequestId><HostId>SOME_HOST_ID</HostId></Error>

我刚刚添加了适用于我在大约 10 到 15 分钟前尝试的域的 CORS 规则。但我的印象是它应该立即发生。

是否需要破坏一些远程缓存才能使浏览器正常工作?我在普通模式和隐身模式下都试过了。

此外,根据 的结果curl,似乎我不再收到Access-Control-Allow-Origin标题错误,对吧?所以,理论上,它应该在我的浏览器中工作。

我是否误读了命令行中发生的事情?

我还缺少什么?

4

3 回答 3

0

检查您发送到服务器的请求,然后才能发送 POST 请求 OPTIONS 请求(chrome 执行此操作)

我得到 CORS 的 Precondition Failed 错误,因为只允许 POST 方法,允许 OPTIONS 方法解决了这个问题。

于 2016-02-16T19:17:28.117 回答
0

这是我所做的一个稍微的解决方案。我在 S3 中设置了策略,以允许仅将限制域作为引用者将内容放入存储桶

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AddPerm",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::myapp/*",
            "Condition": {
                "StringLike": {
                    "aws:Referer": "http://prod-myapp.herokuapp.com/*"
                }
            }
        }
    ]
}

因此您可以通过以下方式测试 PUT 方法

curl -v -H "Referer: http://prod-myapp.herokuapp.com/index.php" -H "Content-Length: 0" -X PUT https://myapp.s3.amazonaws.com/testobject.jpg
于 2015-09-22T08:34:29.360 回答
0

curl 的错误消息说:

At least one of the pre-conditions you specified did not hold
Bucket POST must be of the enclosure-type multipart/form-data

您可以通过使用 -F 选项(例如“-F name=value”)使 curl 使用内容类型“multipart/form-data”。您可以多次使用它来添加您需要的所有表单参数。此页面列出了 S3 预期的参数:

http://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPOST.html

指定“文件”和“密钥”会使您到达失败并出现“拒绝访问”错误的地步。我假设您已将其设置为私有,因此您可能需要“access-key-id”或类似的东西才能超越这一点。

curl -v -H "Origin: http://prod-myapp.herokuapp.com" -X POST \
    https://myapp.s3.amazonaws.com -F key=wibble -F file=value

此外,根据 curl 的结果,似乎我不再收到 Access-Control-Allow-Origin 标头错误,对吧?所以,理论上,它应该在我的浏览器中工作。

是否指定 -H origin 选项实际上似乎没有什么区别,所以我不确定你的 CORS 设置是否真的有任何效果。

于 2016-02-16T13:50:42.377 回答