我的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
标头错误,对吧?所以,从理论上讲,它应该在我的浏览器中工作。
我是否误读了命令行中发生的事情?
我还缺少什么?
答案 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方法解决了这个问题。