AJAX from S3 CORS fails on preflight OPTIONS with 403

解决办法:

<!-- Sample policy -->
<CORSConfiguration>
    <CORSRule>
        <AllowedOrigin>*</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <MaxAgeSeconds>3000</MaxAgeSeconds>
        <AllowedHeader>Authorization</AllowedHeader>
    </CORSRule>
</CORSConfiguration>

改为:

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <CORSRule>
        <AllowedOrigin>*</AllowedOrigin> //The '*' wildcard character refers to all origins.
        <AllowedMethod>GET</AllowedMethod>
        <AllowedMethod>PUT</AllowedMethod>
        <MaxAgeSeconds>3000</MaxAgeSeconds>
        <AllowedHeader>*</AllowedHeader> //The rule also allows all headers in a pre-flight OPTIONS request through the Access-Control-Request-Headers header.
    </CORSRule>
</CORSConfiguration>

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

http://stackoverflow.com/questions/26691286/amazon-s3-bucket-returning-403-forbidden

cloudFront上配置cors:

http://stackoverflow.com/questions/12229844/amazon-s3-cors-cross-origin-resource-sharing-and-firefox-cross-domain-font-loa

 

Chrome console中的报错信息:

jquery.min.js:4 OPTIONS https://hello.s3-ap-south-1.amazonaws.com/20170303/jakartaSnsTest…Signature=b03ff312f553715bee852c1ce9122e13cb52bd8c88e53826dfcfb521efb2f9e4 403 (Forbidden)
send @ jquery.min.js:4
ajax @ jquery.min.js:4
putObject @ upload.js:7
upload @ upload.js:39
uploadFile @ upload.js:46
submit @ (index):40
onclick @ (index):26
(index):1 XMLHttpRequest cannot load https://hello.s3-ap-south-1.amazonaws.com/20170303/jakartaSnsTest…Signature=b03ff312f553715bee852c1ce9122e13cb52bd8c88e53826dfcfb521efb2f9e4. 
Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost' is therefore not allowed access. 
The response had HTTP status code 403.
upload.js:42 Put object failed, status:0, error:
2jquery.min.js:4 OPTIONS https://hello.s3-ap-south-1.amazonaws.com/20170303/jakartaSnsTest…Signature=b03ff312f553715bee852c1ce9122e13cb52bd8c88e53826dfcfb521efb2f9e4 403 (Forbidden)
send @ jquery.min.js:4
ajax @ jquery.min.js:4
putObject @ upload.js:7
upload @ upload.js:39
uploadFile @ upload.js:46
submit @ (index):40
onclick @ (index):26
(index):1 XMLHttpRequest cannot load https://hello.s3-ap-south-1.amazonaws.com/20170303/jakartaSnsTest…Signature=b03ff312f553715bee852c1ce9122e13cb52bd8c88e53826dfcfb521efb2f9e4. 
Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. 
Origin 'http://localhost' is therefore not allowed access. The response had HTTP status code 403.
Put object failed, status:0, error:

 Response中的报错信息:

<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-Request-Headers are not whitelisted by the resource's CORS spec.
</Message>
<Method>PUT</Method>
<ResourceType>OBJECT</ResourceType>
<RequestId>A52988E0AA20EEC7</RequestId>
<HostId>9f9kf10MxX5Aw3o7vZD0QNN4kkkB6Bwmo9nWK7cTf8eJlnsve3E988MXFJ8rPejgiaqSE00QOms=</HostId>
</Error>

 

 相关资料:

同源策略解析:

同源策略限制从一个源加载的文档或脚本如何与来自另一个源的资源进行交互。

一个定义

如果协议,端口(如果指定了一个)和主机对于两个页面是相同的,则两个页面具有相同的

下表给出了相对http://store.company.com/dir/page.html同源检测的示例:

URL 结果 原因
http://store.company.com/dir2/other.html 成功 dir2/other.html
http://store.company.com/dir/inner/another.html 成功 dir/inner/another.html
https://store.company.com/secure.html 失败 不同的协议 ( https )
http://store.company.com:81/dir/etc.html 失败 不同的端口 ( 81 )
http://news.company.com/dir/other.html 失败 不同的主机 ( news )

https://developer.mozilla.org/zh-CN/docs/Web/Security/Same-origin_policy

 

跨源资源共享:使用案例场景

以下是有关使用 CORS 的示例场景:

  • 场景 1:假设您在名为 website 的 Amazon S3 存储桶中托管网站(如在 Amazon S3 上托管静态网站中所述)。您的用户加载了网站终端节点 http://website.s3-website-us-east-1.amazonaws.com。现在,您想要使用存储的网页上(存储在此存储桶中)的 JavaScript,以使用该存储桶的 Amazon S3 API 终端节点 website.s3.amazonaws.com 向同一存储桶发送经身份验证的 GET 和 PUT 请求。浏览器通常会阻止 JavaScript 允许这些请求,但借助 CORS,您可以配置您的存储桶以显式支持来自 website.s3-website-us-east-1.amazonaws.com 的跨源请求。
  • 场景 2:假设您想要托管来自您的 S3 存储桶的 Web 字体。浏览器会再次要求对正在加载的 Web 字体进行 CORS 检查(也称为预检),因此您应该配置托管此 Web 字体的存储桶以允许任意源发送这些请求。

如何在我的存储桶上配置 CORS?

要将您的存储桶配置为允许跨源请求,您可以创建一个 CORS 配置,即一个 XML 文档,其中包含一些规则,它们能够识别您允许访问存储桶的源、每个源支持的操作(HTTP 方法),以及其他特定操作的信息。

您可以向配置添加最多 100 条规则。通过编程方式或者使用 控制台将 XML 文档作为 cors 子资源 添加到存储桶 Amazon S3。有关更多信息,请参阅 允许跨源资源共享 (CORS)

以下示例 cors 配置具有三个规则,这些规则被指定为 CORSRule 元素:

  • 第一个规则允许来自 https://www.example1.com 源的跨源 PUT、POST 和 DELETE 请求。该规则还通过 Access-Control-Request-Headers 标头允许预检 OPTIONS 请求中的所有标头
    作为对任何预检 OPTIONS 请求的响应,Amazon S3 将返回请求的任意标头。
  • 第二个规则允许与第一个规则具有相同的跨源请求,但第二个规则应用于另一个源 https://www.example2.com
  • 第三个规则允许来自所有源的跨源 GET 请求。“*”通配符字符是指所有的源
<CORSConfiguration>
 <CORSRule>
   <AllowedOrigin>http://www.example1.com</AllowedOrigin>

   <AllowedMethod>PUT</AllowedMethod>
   <AllowedMethod>POST</AllowedMethod>
   <AllowedMethod>DELETE</AllowedMethod>

   <AllowedHeader>*</AllowedHeader>
 </CORSRule>
 <CORSRule>
   <AllowedOrigin>http://www.example2.com</AllowedOrigin>

   <AllowedMethod>PUT</AllowedMethod>
   <AllowedMethod>POST</AllowedMethod>
   <AllowedMethod>DELETE</AllowedMethod>

   <AllowedHeader>*</AllowedHeader>
 </CORSRule>
 <CORSRule>
   <AllowedOrigin>*</AllowedOrigin>
   <AllowedMethod>GET</AllowedMethod>
 </CORSRule>
</CORSConfiguration>

 

CORS 配置还允许可选的配置参数,如下面的 CORS 配置所示。在本示例中,下面的 CORS 配置允许来自 http://www.example.com 源的跨源 PUT、POST 和 DELETE 请求。

<CORSConfiguration>
 <CORSRule>
   <AllowedOrigin>http://www.example.com</AllowedOrigin>
   <AllowedMethod>PUT</AllowedMethod>
   <AllowedMethod>POST</AllowedMethod>
   <AllowedMethod>DELETE</AllowedMethod>
   <AllowedHeader>*</AllowedHeader>
  <MaxAgeSeconds>3000</MaxAgeSeconds>
  <ExposeHeader>x-amz-server-side-encryption</ExposeHeader>
  <ExposeHeader>x-amz-request-id</ExposeHeader>
  <ExposeHeader>x-amz-id-2</ExposeHeader>
 </CORSRule>
</CORSConfiguration>

上述配置中的 CORSRule 元素包括以下可选元素:

  • MaxAgeSeconds - 指定在 Amazon S3 针对特定资源的预检 OPTIONS 请求做出响应后,浏览器缓存该响应的时间(以秒为单位)(在本示例中,为 3000 秒)。通过缓存响应,在需要重复原始请求时,浏览器无需向 Amazon S3 发送预检请求。
  • ExposeHeader – 识别可允许客户从应用程序(例如,从 JavaScript XMLHttpRequest 对象)进行访问的响应标头(在本示例中,为 x-amz-server-side-encryptionx-amz-request-id 和 x-amz-id-2)。

AllowedMethod 元素

在 CORS 配置中,您可以为 AllowedMethod 元素指定以下值。

  • GET
  • PUT
  • POST
  • DELETE
  • HEAD

AllowedOrigin 元素

在 AllowedOrigin 元素中,指定要允许从其发送跨源请求的源,例如 http://www.example.com。源字符串可包含至少一个 * 通配符字符,例如 http://*.example.com。您可以选择将 * 指定为源,以允许所有源发送跨源请求。您还可以指定 https 只允许安全的源。

AllowedHeader 元素

AllowedHeader 元素通过 Access-Control-Request-Headers 标头指定预检请求中允许哪些标头。Access-Control-Request-Headers 标头中的每个标头名称必须匹配规则中的相应条目。Amazon S3 将仅发送请求的响应中允许的标头。有关可以在发送至 Amazon S3 的请求中使用的标头示例列表,请参阅 Amazon Simple Storage Service API Reference 指南中的常用请求标头

规则中的每个 AllowedHeader 字符串可以包含至少一个 * 通配符字符。例如,<AllowedHeader>x-amz-*</AllowedHeader> 将允许所有特定于 Amazon 的标头。

ExposeHeader 元素

每个 ExposeHeader 元素标识您希望客户能够从其应用程序(例如,从 JavaScript XMLHttpRequest 对象)进行访问的响应标头。有关常用 Amazon S3 响应标头的列表,请参阅 Amazon Simple Storage Service API Reference 指南中的常用响应标头

MaxAgeSeconds 元素

MaxAgeSeconds 元素指定在预检请求被资源、HTTP 方法和源识别之后,浏览器将为预检请求缓存响应的时间(以秒为单位)。

Amazon S3 如何评估针对存储桶的 CORS 配置?

Amazon S3 收到来自浏览器的预检请求后,它将为存储桶评估 CORS 配置,并使用第一个匹配传入浏览器请求的 CORSRule规则来实现跨源请求。要使规则实现匹配,必须满足以下条件:

  • 请求的 Origin 标头必须匹配 AllowedOrigin 元素。
  • 预检 OPTIONS 请求中的请求方法(例如,GET 或 PUT)或 Access-Control-Request-Method 标头必须是某个 AllowedMethod 元素。
  • 在预检请求中,请求的 Access-Control-Request-Headers 标头中列出的每个标头必须匹配 AllowedHeader 元素。

Note

使存储桶允许 CORS 后,ACL 和策略仍适用。

 http://docs.aws.amazon.com/zh_cn/AmazonS3/latest/dev/cors.html

 

时间: 2025-01-27 03:10:22

AJAX from S3 CORS fails on preflight OPTIONS with 403的相关文章

ASP.NET Web API 2 对 CORS 的支持

跨域资源共享 (CORS) 是一种万维网联合会 (W3C) 规范(通常被认为是 HTML5 的一部分),它可让 JavaScript 克服由浏览器施加的同域策略安全限制.所谓同域策略,就是 JavaScript 只能对包含网页的同 一个域进行 AJAX 回调(其中,"域"就是主机名.协议和端口号的组合).例如, http://foo.com 中某个网页上的 JavaScript 无法对 http://bar.com(或 http://www.foo.com. https://foo.c

JQuery AJAX提交中文乱码的解决方案_jquery

现象如下: 1)在Firefox下,处理页面的编码为gb2312,提交数据没有问题,中文能够正确解析: 2)在IE8下,处理页面的编码为gb2312,提交中文数据出现乱码. 无论是$.post还是$.ajax,抑或$.ajaxSubmit(来自于Form插件),在之前的UTF-8编码的网站都没有出现过任何问题, 看来是由于提交数据的网页的编码格式造成的了.不管怎么样,既然是浏览器之间存在差异,还是从HTTP包来看有什么问题吧. 打开Fiddle,分别用Firefox和IE做一个AJAX提交(以用

Web API 2 对 CORS 的支持

原文:Web API 2 对 CORS 的支持 Web API 2 对 CORS 的支持 CORS概念 跨域资源共享 (CORS) 是一种万维网联合会 (W3C) 规范(通常被认为是 HTML5 的一部分),它可让 JavaScript 克服由浏览器施加的同域策略安全限制. 所谓同域策略,就是 JavaScript 只能对包含网页的同一个域进行 AJAX 回调(其中,"域"就是主机名.协议和端口号的组合). 例如,http://foo.com 中某个网页上的 JavaScript 无法

Ajax::prototype 源码解读_javascript技巧

AJAX之旅(1):由prototype_1.3.1进入javascript殿堂-类的初探  还是决定冠上ajax的头衔,毕竟很多人会用这个关键词搜索.虽然我认为这只是个炒作的概念,不过不得不承认ajax叫起来要方便多了.所以ajax的意思我就不详细解释了. 写这个教程的起因很简单:经过一段时间的ajax学习,有一些体会,并且越发认识到ajax技术的强大,所以决定记录下来,顺便也是对自己思路的整理.有关这个教程的后续,请关注http://www.x2design.net 前几年,javascri

jQuery AJAX保存数据中文乱码解决方案

在处理一个GB2312编码的网站,用jQuery AJAX提交时,无论是在数据库,还是load返回页面,中文数据都变成了乱码. jQuery AJAX中文乱码原因在于javascript使用的是UTF-8国际编码,UTF-8每个汉字用4个字节来存储.而我的页面和数据库都用GB2312编码,这就造成了AJAX send数据的时候出现中文乱码的问题. 解决方法是,所有的页面编码声明都用utf-8,数据库.表.字段也用utf-8.    代码如下 复制代码 <meta http-equiv="C

ajax注册应用三

我们来看最后一个js 文件 var Prototype = {   Version: '1.4.0',   ScriptFragment: '(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)',   emptyFunction: function() {},   K: function(x) {return x} } var Class = {   create: function() {     return function() {     

jquery ajax异步请求 接收返回json数据

例子  代码如下 复制代码 $('#send').click(function () {     $.ajax({         type : "GET",         url : "a.php",         dataType : "jsonp",         success : function (data) {             $.each(data.items, function (i, item) {       

php ajax 分页三

再来看protype.js文件. /*  Prototype JavaScript framework, version 1.5.0  *  (c) 2005-2007 Sam Stephenson  *  *  Prototype is freely distributable under the terms of an MIT-style license.  *  For details, see the Prototype web site: http://prototype.conio.

Spring处理跨域请求

[nio-8080-exec-8] o.s.web.cors.DefaultCorsProcessor        : Skip CORS processing: request is from same origin   一次正常的请求 最近别人需要调用我们系统的某一个功能,对方希望提供一个api让其能够更新数据.由于该同学是客户端开发,于是有了类似以下代码. @RequestMapping(method = RequestMethod.POST, value = "/update.json