kat*_*ray 59 amazon-s3 cors amazon-cloudfront
我的应用程序将图像存储在S3上,然后通过Cloudfront代理它们.我很高兴使用新的S3 CORS支持,以便我可以使用HTML5 canvas方法(具有跨源策略),但似乎无法正确配置我的S3和Cloudfront.当我尝试将图像转换为canvas元素时,仍然遇到"Uncaught Error:SECURITY_ERR:DOM Exception 18".
这是我到目前为止所拥有的:
S3
<CORSConfiguration>
<CORSRule>
<AllowedOrigin>MY_WEBSITE_URL</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<MaxAgeSeconds>3000</MaxAgeSeconds>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
<CORSRule>
<AllowedOrigin>MY_CLOUDFRONT_URL</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>
Run Code Online (Sandbox Code Playgroud)
CloudFront的
起源
Origin Protocol Policy: Match Viewer
HTTP Port: 80
HTTPS Port: 443
Run Code Online (Sandbox Code Playgroud)
行为
Origin: MY_WEBSITE_URL
Object Caching: Use Origin Cache Headers
Forward Cookies: None
Forward Query Strings: Yes
Run Code Online (Sandbox Code Playgroud)
这里有什么我想念的吗?
更新:刚尝试将标题更改为
<AllowedHeader>Content-*</AllowedHeader>
<AllowedHeader>Host</AllowedHeader>
Run Code Online (Sandbox Code Playgroud)
基于这个问题的Amazon S3 CORS(跨域资源共享)和Firefox跨域字体加载
仍然没有去.
更新:更多信息请求
Request
URL:https://d1r5nr1emc2xy5.cloudfront.net/uploaded/BAhbBlsHOgZmSSImMjAxMi8wOS8xMC8xOC81NC80Mi85NC9ncmFzczMuanBnBjoGRVQ/32c0cee8
Request Method:GET
Status Code:200 OK (from cache)
Run Code Online (Sandbox Code Playgroud)
UPDATE
我想也许我的请求不正确,所以我尝试启用CORS
img.crossOrigin = '';
Run Code Online (Sandbox Code Playgroud)
但然后图像没有加载,我得到错误:跨源资源共享策略拒绝跨源图像加载.
Bre*_*ett 114
2014年6月26日,AWS 在CloudFront上发布了适当的Vary:Origin行为,现在您就可以了
为S3存储桶设置CORS配置,包括
<AllowedOrigin>*</ AllowedOrigin>
在CloudFront - > Distribution - >此行为的行为中,使用Forward Headers:Whiteelist选项并将'Origin'标题列入白名单.
等待~20分钟,而CloudFront传播新规则
现在,您的CloudFront分配应该为不同的客户端Origin头缓存不同的响应(使用正确的CORS头).
Nik*_*kov 40
2022年答案:
[
{
"AllowedHeaders": [],
"AllowedMethods": [
"GET"
],
"AllowedOrigins": [
"*"
],
"ExposeHeaders": []
}
]
Run Code Online (Sandbox Code Playgroud)
这将允许来自所有来源的 GET 请求。根据您的项目需求进行修改。
转到您的CloudFront 发行版 -> 行为 -> 编辑(在我的例子中,我只有一种行为)
向下滚动到缓存密钥和源请求
选择缓存策略和源站请求策略(推荐)
在源请求策略下- 可选选择CORS-CustomOrigin
保存更改
完毕!
Chr*_*son 29
补充@ Brett的答案.有AWS文档页面细节上CloudFront的CORS和S3上CORS.
详细步骤如下:
<AllowedOrigin>规则是重要的规则.保存配置.

OPTIONS缓存响应,根据AWS,有两种方法:
- 如果要缓存OPTIONS响应,请执行以下操作:
- 选择为OPTIONS响应启用缓存的默认缓存行为设置选项.
- 配置CloudFront以转发以下标头:Origin,Access-Control-Request-Headers和Access-Control-Request-Method.
- 如果您不希望缓存OPTIONS响应,请将CloudFront配置为转发Origin标头以及您的源所需的任何其他标头
而使用来自CloudFront和S3的CORS应该可行.
小智 19
2023 年 3 月 - 这对我有用。
S3 存储桶的跨源资源共享 (CORS)策略(存储桶详细信息 > 权限)。调整AllowedOrigins,适合您的项目(您可以在设置测试期间AllowedHeaders使用)。*
[
{
"AllowedHeaders": [
"*"
],
"AllowedMethods": [
"GET",
"HEAD"
],
"AllowedOrigins": [
"*"
],
"ExposeHeaders": []
}
]
Run Code Online (Sandbox Code Playgroud)
转到 Cloudfront distribution > 编辑行为(在大多数情况下,每个发行版只有一个)
小智 6
作为之前答案的补充,我想分享一下有关如何启用 CORS 的 AWS 步骤。我发现它非常有用,提供了额外的链接:https ://aws.amazon.com/premiumsupport/knowledge-center/no-access-control-allow-origin-error/
此外,在测试更改时,除了 CloudFront 部署延迟之外,还应该考虑浏览器缓存。我建议在测试您的更改时使用不同的隐身会话。
我遵循了AWS文档:
然后我使用 aws cdk 来帮我做这件事。完整源代码在这里: https: //github.com/quincycs/quincymitchell.com
const myBucket = new Bucket(this, 'bucket', {
bucketName: `prod-${domainName}`,
cors: [{
allowedMethods: [HttpMethods.GET],
allowedOrigins: ['*'],
allowedHeaders: ['*']
}],
enforceSSL: true,
blockPublicAccess: BlockPublicAccess.BLOCK_ALL,
removalPolicy: RemovalPolicy.RETAIN
});
const mycert = Certificate.fromCertificateArn(this, 'certificate', ssmCertArn);
new Distribution(this, 'myDist', {
defaultBehavior: {
origin: new S3Origin(myBucket),
viewerProtocolPolicy: ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
originRequestPolicy: OriginRequestPolicy.CORS_S3_ORIGIN,
responseHeadersPolicy: ResponseHeadersPolicy.CORS_ALLOW_ALL_ORIGINS,
allowedMethods: AllowedMethods.ALLOW_GET_HEAD_OPTIONS, // needed for cors
cachedMethods: CachedMethods.CACHE_GET_HEAD_OPTIONS, // needed for cors
},
defaultRootObject: 'index.html',
domainNames: [domainName, `www.${domainName}`],
certificate: mycert
});
Run Code Online (Sandbox Code Playgroud)
更新:CloudFront上的最新更改已不再适用。pp!有关详细信息,请参见其他响应。我将其保留在此处以用于上下文/历史记录。
问题
CloudFront不支持100%的CORS。问题是CloudFront如何缓存对请求的响应。此后,对同一URL的任何其他请求将导致缓存请求无论其来源如何。关于它的关键部分是它包括来自起点的响应头。
CloudFront缓存了任何内容之前的第一个请求Origin: http://example.com的响应标头为:
Access-Control-Allow-Origin: http://example.com
Run Code Online (Sandbox Code Playgroud)
来自的第二个请求Origin: https://example.com(请注意,它是HTTPS而不是HTTP)也具有以下响应标头:
Access-Control-Allow-Origin: http://example.com
Run Code Online (Sandbox Code Playgroud)
因为那是CloudFront为URL缓存的内容。这是无效的-浏览器控制台(至少在Chrome中)将显示CORS违规消息,并且一切都会中断。
解决方法
建议的解决方法是对不同的来源使用不同的URL。诀窍是要添加一个唯一的查询字符串,该字符串要有所不同,以便每个源都存在一个缓存的记录。
因此,我们的URL类似于:
http://.../some.png?http_mysite.com
https://.../some.png?https_mysite.com
Run Code Online (Sandbox Code Playgroud)
这种工作方式有效,但是任何人都可以通过交换查询字符串来使您的网站无法正常工作。那可能吗?可能不是,但是调试此问题非常麻烦。
正确的解决方法是在CloudFront完全支持CORS之前,不要将CloudFront与CORS一起使用。
在实践中
如果您将CloudFront用于CORS,则可以使用另一种方法,当CORS不起作用时,该方法将起作用。这并非总是一种选择,但现在我正在使用JavaScript动态加载字体。如果对CloudFront的基于CORS的请求失败,我将退回到字体的服务器端代理(不跨源)。这样,即使CloudFront以某种方式获得了不良的字体缓存记录,事情仍然可以正常进行。
发布一些我为使其工作而进行的重要配置:
将自定义域分配给 cloudfront,以便自定义域成为应用程序前端运行的子域。在 OP 的例子中,他使用的是 localhost:3000; 他很可能正在测试他的开发设置,但他必须在某个域中部署此应用程序:我们称之为“myapp.com”。因此,他可以分配一个自定义域,例如 cdn.myapp.com 指向 blah.cloudfront.net。您将需要为新的自定义域创建/导入自定义 SSL 证书;默认的cloudfront证书将不起作用。
请参阅:https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/CNAMEs.html 
在 Cloudfront 分发快照中,第一行没有自定义域,因此 CNAME 列为空。第二个是有一个自定义域,因此我们在那里打印了一个。您可以通过这种方式验证您的自定义域是否已指向 Cloudfront 发行版。
Cloudfront 行为:我假设您已经设置了受信任的密钥组,此时您已经拥有签名的 cookie。但是,您将需要创建自定义缓存策略和源请求策略。
请参阅以下自定义缓存策略的屏幕截图:
和原产地请求政策:
需要注意的是,您需要将这些标头列入白名单:Origin、Access-Control-Request-Method、Access-Control-Allow-Origin、Access-Control-Request-Headers。(您可能会注意到 Access-Control-Allow-Origin 不在下拉列表中;只需继续输入即可!)。另外,允许所有 cookie。
S3 CORS 配置:转到 S3 存储桶并单击权限选项卡。向下滚动到 CORS 配置。免责声明:我只是粘贴了对我有用的内容。其背后的基本原理是,在我的场景中,该 S3 将由 CDN 或应用程序访问。我尝试将“*”放宽,但 Chrome 上的 CORS 政策抱怨我无法在 AllowedOrigins 中使用通配符条目!
Run Code Online (Sandbox Code Playgroud)[ { "AllowedHeaders": [ "*" ], "AllowedMethods": [ "PUT", "POST", "GET", "HEAD", "DELETE" ], "AllowedOrigins": [ "cdn.myapp.com", "myapp.com", "https://cdn.myapp.com", "https://myapp.com" ], "ExposeHeaders": [ "ETag" ] } ]
Run Code Online (Sandbox Code Playgroud)<ReactPlayer className="react-player" url={url} controls={controls} light={light} config={ { file: { forceHLS: true, hlsOptions: { xhrSetup: function (xhr, url) { xhr.withCredentials = true; // send cookies }, }, }, } } playIcon={<PlayIcon />} width="100%" height="100%" />
| 归档时间: |
|
| 查看次数: |
37356 次 |
| 最近记录: |