允许来自 Amazon S3 的 AJAX GET? (访问控制允许来源)

Posted

技术标签:

【中文标题】允许来自 Amazon S3 的 AJAX GET? (访问控制允许来源)【英文标题】:Allow AJAX GETs from Amazon S3? (Access-Control-Allow-Origin) 【发布时间】:2012-07-04 04:15:55 【问题描述】:

我将 JSON 对象存储在 Amazon S3 中,我想直接从 javascript 中的 S3 加载该数据。我的 GET 看起来很一般:

$.ajax(
    'type':'GET',
    'url':'http://s3.amazonaws.com/mybucketname/'+id,
    'dataType':'text',
    'success':function(msg) 
        alert(msg);
    
);

我收到以下错误:

XMLHttpRequest cannot load http://s3.amazonaws.com/whatever/whatever. Origin http://mylocalhostname:9000 is not allowed by Access-Control-Allow-Origin.

我可以使用 curl 从 S3 获取该 URL,或者直接从我的浏览器导航到那里。我真的必须通过我自己的服务器代理所有这些请求吗?

【问题讨论】:

Amazon S3 and Cross-Origin Resource Sharing (CORS) 的可能重复项 或另一个骗子:***.com/questions/8674776/… 显示 JSONP 解决方案。 【参考方案1】:

如果您使用通配符 *,S3 不会发送“Access-Control-Allow-Origin”标头:

<AllowedOrigin>*</AllowedOrigin>

要强制 s3 发送 AllowedOrigin 标头但仍让您的内容从任何站点加载,请使用以下命令:

<AllowedOrigin>http://*</AllowedOrigin>
<AllowedOrigin>https://*</AllowedOrigin>

【讨论】:

搜遍了,这就是我的解决方案。不在亚马逊的文档中,但立即起作用。您可以在同一个 CORS 规则中列出所有三个 同样,在我尝试的所有修复中,这是灵丹妙药。 这也为我做了。我不知所措。花了两个小时尝试了我能想到的一切,但没有任何效果。您可能会认为他们会在文档中提及这一点,或者如果没有提及,则进行更改,以使任何一种方式都能按预期工作。 也为我工作!我试图使用 jquery 加载函数将 html 文件从 S3 加载到 Heroku。 与@AdrienRenaud 非常相似,使用原生 XMLHTTPRequest() 类解决了我的 HTML 文件问题。【参考方案2】:

S3 现在支持使用 CORS 文件的跨域请求。

您可以在此处找到更多信息:

http://docs.amazonwebservices.com/AmazonS3/latest/dev/cors.html#how-do-i-enable-cors

和:

http://aws.typepad.com/aws/2012/08/amazon-s3-cross-origin-resource-sharing.html

【讨论】:

这不是cors 文件,而是cors 子资源。因此,对于那些试图在您的存储桶中转储名为 cors 的文件的人来说,这是行不通的。 (我自己试过了。) 只是关于 S3 的 cors 的注释。应用策略时,存储桶中已有的文件不会更新。因此,请确保仅将 CORS 策略应用于新存储桶,或在应用策略后重新添加内容。 @samsamm777 我正面临这个问题。我无法更新 s3 存储桶中的现有文件。如何使用 CORS 更新 s3 存储桶中的现有文件?【参考方案3】:

搜索了很多 - 这是示例解决方案:

http://blog.bignerdranch.com/1670-upload-directly-to-amazon-s3-with-support-for-cors/

(在存储桶权限选项卡上添加 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>

【讨论】:

【参考方案4】:

我们遇到了类似的问题,但不是使用 GET,而是使用预签名的 S3 POST。我认为这可能对搜索此问题的人有所帮助。

在某些浏览器中,Dropzone.js lib 无法将图像直接上传到 S3 存储桶(预签名的 S3 POST)。奇怪的是,这一直在某些计算机上发生,并且在二十次尝试中发生。

在一台计算机上,我们设法在 Firefox 调试器(网络选项卡)中捕获错误

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://s3-eu-west-1.amazonaws.com/pobble.com-browser-uploads-production. (Reason: CORS header 'Access-Control-Allow-Origin' missing).

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://s3-eu-west-1.amazonaws.com/pobble.com-browser-uploads-production. (Reason: CORS request failed).

将 S3 存储桶 CORS 更新为此对我们有用:

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <CORSRule>
        <AllowedOrigin>http://www.myapp.com</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <AllowedMethod>POST</AllowedMethod>
        <AllowedMethod>PUT</AllowedMethod>
        <AllowedHeader>*</AllowedHeader>
        <ExposeHeader>Accept-Ranges</ExposeHeader>
        <ExposeHeader>Content-Range</ExposeHeader>
        <ExposeHeader>Content-Encoding</ExposeHeader>
        <ExposeHeader>Content-Length</ExposeHeader>
        <ExposeHeader>Access-Control-Allow-Origin</ExposeHeader>
    </CORSRule>
    <CORSRule>
        <AllowedOrigin>https://www.app.com</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <AllowedMethod>POST</AllowedMethod>
        <AllowedMethod>PUT</AllowedMethod>
        <AllowedHeader>*</AllowedHeader>
        <ExposeHeader>Accept-Ranges</ExposeHeader>
        <ExposeHeader>Content-Range</ExposeHeader>
        <ExposeHeader>Content-Encoding</ExposeHeader>
        <ExposeHeader>Content-Length</ExposeHeader>
        <ExposeHeader>Access-Control-Allow-Origin</ExposeHeader>
    </CORSRule>
</CORSConfiguration>

重要的部分是 &lt;ExposeHeader&gt;Access-Control-Allow-Origin&lt;/ExposeHeader&gt;,这要归功于这个 S3 暴露了响应头 OPTIONSPOST

@anas-alaoui、@joserose 和 @equivalent 的协作工作

【讨论】:

【参考方案5】:

您可以使用 jsonp 请求代替 json。这是详细信息。 http://api.jquery.com/jQuery.ajax/

【讨论】:

是的,但请参阅 Amazon CORS 文档以及这是(最近)亚马逊支持的用于选择性启用域的选项。【参考方案6】:

我也在为同样的问题苦苦挣扎。唯一的区别是我想从我的 S3 中提取一个带有 Ajax 的文件并将其加载到一个站点中。

经过大量搜索后,我最终将此选项添加到我的 Ajax 请求中。

xhrFields: withCredentials: true ,

只要你有 CORSConfiguration 允许所有的人,它就像一个魅力。

希望对你有帮助。

【讨论】:

【参考方案7】:
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <CORSRule>
        <AllowedOrigin>http://*</AllowedOrigin>
        <AllowedOrigin>https://*</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <AllowedHeader>*</AllowedHeader>
    </CORSRule>
</CORSConfiguration>

这个 CORS 配置就像一个魅力

【讨论】:

【参考方案8】:

这是我的提示来自:https://github.com/mozilla/pdf.js/issues/3150

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <CORSRule>
        <AllowedOrigin>*</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <AllowedHeader>*</AllowedHeader>
        <ExposeHeader>Accept-Ranges</ExposeHeader>
        <ExposeHeader>Content-Range</ExposeHeader>
        <ExposeHeader>Content-Encoding</ExposeHeader>
        <ExposeHeader>Content-Length</ExposeHeader>
    </CORSRule>
</CORSConfiguration>

【讨论】:

【参考方案9】:

如果您有较大的文件需要更长时间下载,您可能需要增加 MAX AGE 配置,或者它们可能会提前中断。媒体托管等将需要这个。我的通配符访问(任何域)的配置最长为 10000 秒,这应该比任何人下载我的文件所需的时间都要长,即使连接不好:

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

【讨论】:

【参考方案10】:

对于任何在这个问题上苦苦挣扎的人,正如其他人所说,您必须通过将这些行添加到您的 CORS 配置中来强制 S3 使用 CORS 标头进行响应:

<AllowedOrigin>http://*</AllowedOrigin>
<AllowedOrigin>https://*</AllowedOrigin>

但是,您必须清除浏览器文件缓存,因为存储了所请求资源上的旧标头。在 Chrome 中,找到清除浏览数据选项,然后选择清除文件缓存。硬重新加载不会清除某些文件。如果您希望只清除当前站点的文件缓存,this answer 会解释如何做到这一点。

这对我来说是个问题。

【讨论】:

【参考方案11】:

就我而言,我想从存储桶“myBucket”中获取一些资源。

在 S3 客户端,AWS S3 现在支持 JSON 来配置 CORS 策略[ref]

存储桶政策:

[
    
        "AllowedHeaders": [
            "*",
            "x-amz-*"
        ],
        "AllowedMethods": [
            "GET",
            "HEAD"
        ],
        "AllowedOrigins": [
            "*"
        ],
        "ExposeHeaders": []
    
]

在服务器端/客户端(JQUERY Ajax

$.ajax(
    type: "GET", 
    url: "https://myBucket/myObject",
);​​​​​​​​​​​​​​​

试试吧!希望对你有帮助!

【讨论】:

影响将在设置 CORS 政策后 2-10 分钟左右生效。至少我要等将近5分钟才能通过AJAX请求获取bucket对象。

以上是关于允许来自 Amazon S3 的 AJAX GET? (访问控制允许来源)的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 PHP 显示来自 Amazon S3 的图像?

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

Amazon S3 - 尽管有 GetObject 限制,但返回 403 错误而不是 404

Amazon S3 存储桶 GET 请求计数

如何只允许特定用户访问 Amazon S3 上的内容

Amazon S3 策略只允许上传而不是覆盖 [重复]