我的CORS规则不能解决我的CORS错误

时间:2015-09-17 05:00:43

标签: amazon-s3 cors

我的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标头错误,对吧?所以,从理论上讲,它应该在我的浏览器中工作。

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

我还缺少什么?

3 个答案:

答案 0 :(得分:0)

这是我所做的一个轻微的解决方案。 我在S3中设置策略以允许仅通过限制域将内容作为referer

进行存储
{
    "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

答案 1 :(得分: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

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

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

指定&#34;文件&#34;和&#34;关键&#34;通过&#34; Access Denied&#34;来帮助您达到失败的程度错误。我假设您已将其设置为私有,因此您可能需要&#34; access-key-id&#34;或类似的超越这一点。

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设置是否真的有效。

答案 2 :(得分:0)

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

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