来自 S3 CORS 的 AJAX GET 在预检选项上失败,出现 403

Posted

技术标签:

【中文标题】来自 S3 CORS 的 AJAX GET 在预检选项上失败,出现 403【英文标题】:AJAX GET from S3 CORS fails on preflight OPTIONS with 403 【发布时间】:2015-11-24 21:39:30 【问题描述】:

我看到了几个问题并对此进行了讨论,但仍然找不到任何答案。 我正在尝试使用 AJAX GET 对来自 S3 的文件进行简单的 GET。 我为 CORS 配置的存储桶:

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <CORSRule>
        <AllowedOrigin>*</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <MaxAgeSeconds>3000</MaxAgeSeconds>
        <AllowedHeader>*</AllowedHeader>
    </CORSRule>
</CORSConfiguration>

这是我调用的 curl sn-p(省略文件..):

curl 'https://s3.amazonaws.com/mybucket/myfile.tar.gz
-X OPTIONS 

-H 'Access-Control-Request-Method: GET' 
-H 'Origin: http://0.0.0.0:9000' 
-H 'Referer: http://0.0.0.0:9000/' 
-H 'Access-Control-Request-Headers: accept, x-longtostring' 

-H 'Pragma: no-cache' 
-H 'Accept-Encoding: gzip, deflate, sdch' 
-H 'Accept-Language: en-US,en;q=0.8,he;q=0.6,mg;q=0.4' 
-H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_3) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/44.0.2403.125 Safari/537.36' 
-H 'Accept: */*' 
-H 'Cache-Control: no-cache' 
-H 'Connection: keep-alive' 
--compressed 
--verbose

我得到一个 403 结果:

 HTTP/1.1 403 Forbidden
 x-amz-request-id: 1F545B4ED302B3AD
 x-amz-id-2: AiQwUgOeVhfxRjYL/13MLBsUQdx8n4bYLhV3TwftDfnMZ+7FhvnxfVAGLCo3WCiT
 Content-Type: application/xml
 Transfer-Encoding: chunked
 Date: Sun, 30 Aug 2015 21:25:17 GMT
 Server AmazonS3 is not blacklisted
 Server: AmazonS3

<?xml version="1.0" encoding="UTF-8"?>
 Connection #0 to host s3.amazonaws.com left intact
<Error><Code>AccessForbidden</Code><Message>CORSResponse: This CORS request is not allowed. This is usually because the evalution of Origin, request method / Access-Control-Request-Method or Access-Control-Requet-Headers are not whitelisted by the resource's CORS spec.</Message><Method>GET</Method></Error>

删除 -X OPTIONS 解决了这个问题。但这是由浏览器自动添加的(我使用的是 Angular $http.get),我无法控制(或者我可以控制吗?)。

谢谢

【问题讨论】:

为什么要预检 get 请求? 我不是。浏览器添加了这个。我正在使用简单的角度 $http.get() 知道如何防止这种预检吗? 好的,我明白为什么我得到了浏览器添加的选项 - 这是因为我使用了一些导致浏览器进行预检的自定义标题。删除客户标题,工作。仍然无法获取我的文件 - 得到 403 - 但它似乎是一个不同的问题。 【参考方案1】:

在我能想到的任何配置中,s3 似乎都不会接受 OPTIONS 调用。 但是对于 GET 请求 - 如果您不添加任何自定义标头,浏览器将不会触发 OPTIONS。

所以我从特定的 $http.get(s3FilePath) 请求中删除了任何自定义标头。

我得到 403 的原因是因为文件没有准备好。文件准备好后,你就做对了。

【讨论】:

以上是关于来自 S3 CORS 的 AJAX GET 在预检选项上失败,出现 403的主要内容,如果未能解决你的问题,请参考以下文章

来自 ASP NET Web API 的 CORS 阻止 Ajax POST 调用 - 对预检请求的响应未通过访问控制检查

Laravel + Plupload 上传到 S3 响应以进行预检无效 - CORS

在 CouchDB 上进行预检的 CORS 请求

预检时间的 CORS 请求是不是耗时?

CORS - 带有“授权”的 Ajax 或 XMLHttpRequest 类型 GET 获取错误 307

避免使用 CORS 预检选项以获得更好的性能