我的许多网站都遇到过依赖S3作为Cloudfront原点的问题。但是,我在允许多个域(而不是允许全局*
)方面存在问题。
我已按照文档here(第一个配置)进行操作。并在这里和那里找到了一些其他随机的SO或论坛答案(第二个配置)
感谢任何帮助。
我设置的CORS规则如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>https://example.com</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<AllowedMethod>HEAD</AllowedMethod>
<AllowedMethod>DELETE</AllowedMethod>
<AllowedMethod>PUT</AllowedMethod>
<AllowedMethod>POST</AllowedMethod>
<MaxAgeSeconds>3000</MaxAgeSeconds>
<AllowedHeader>Authorization</AllowedHeader>
</CORSRule>
<CORSRule>
<AllowedOrigin>http://example.com</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
<CORSRule>
<AllowedOrigin>https://staging.example.com</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
<CORSRule>
<AllowedOrigin>http://example.dev</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>
和
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>https://example.com</AllowedOrigin>
<AllowedOrigin>http://example.com</AllowedOrigin>
<AllowedOrigin>https://staging.example.com</AllowedOrigin>
<AllowedOrigin>http://example.dev</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<AllowedMethod>HEAD</AllowedMethod>
<AllowedMethod>DELETE</AllowedMethod>
<AllowedMethod>PUT</AllowedMethod>
<AllowedMethod>POST</AllowedMethod>
<MaxAgeSeconds>3000</MaxAgeSeconds>
<AllowedHeader>Authorization</AllowedHeader>
</CORSRule>
</CORSConfiguration>
我一直在 https://example.com
所有网站上收到字体来源错误:
来自原点的字体&#39; http://CLOUDFRONTURL&#39;已被跨源资源共享策略阻止加载:No&#39; Access-Control-Allow-Origin&#39;标头出现在请求的资源上。起源&#39; http://example.dev&#39;因此不允许访问。
和
来自原点的字体&#39; http://CLOUDFRONTURL&#39;已被跨源资源共享策略阻止加载:“访问控制 - 允许 - 来源”&#39;标头的值为&#39; https://example.com&#39;这不等于提供的原产地。起源&#39; http://example.dev&#39;因此不允许访问。
答案 0 :(得分:4)
CloudFront根据已从浏览器转发到源服务器的请求标头的所有来缓存对象 - 而不仅仅是路径。
对于要从缓存提供的响应,必须返回该响应以响应之前涉及完全相同请求标头的请求。
这是因为,至少原则上,不同的标头可以触发服务器的不同行为,并且行为良好的缓存不能自行承担。
为了提高对象的可缓存性而不影响其提供正确的响应的能力(即,原始服务器为给定请求返回的响应相同),CloudFront几乎删除了请求标头之前将请求转发到源,并在执行缓存查找时使用剥离的请求版本。
当原始服务器是“自定义”(即非S3)源时,您可以选择要转发到源服务器的标头。
但是当原始服务器是S3时,您仍然可以选择,但只有三个可以选择转发......并且它们都与CORS相关。
[使用S3原点],您可以将CloudFront配置为仅基于三个标题转发和缓存对象:
Access-Control-Request-Headers
,Access-Control-Request-Method
和Origin
。转发这些标头允许CloudFront为启用跨源资源共享(CORS)的网站分发内容。您无法将CloudFront配置为将自定义标头转发到Amazon S3。
如果Origin:
标头至少没有转发,那么S3将无法对其做出反应。启用此标头的转发意味着S3不仅会看到它,并且可能因为存储桶上的CORS配置而修改其响应,而且同一对象的Origin:
的每个变体将导致S3返回的不同(和正确)响应,并由CloudFront为将来的匹配请求进行缓存。
CloudFront无法将自定义标头转发到S3,因为这没有任何意义 - 因为S3存储静态内容,响应在其他标头上不会有所不同,因此转发它们将毫无意义并会降低缓存命中率,许多(据称)不同的响应被缓存,但只是为了响应伴随相同标题的请求而提供。
答案 1 :(得分:0)
dev.mydomain.com
)和域 B(例如 www.mydomain.com
)。cdn.mydomain.com
,它位于 CloudFront 上并指向私有 S3 存储桶。/fonts/myfont.woff
从 www.mydomain.com
请求文件(例如 https://cdn.mydomain.com/fonts/myfont.woff
,需要 CORS,per MDN)时,可以访问这些文件。 (到目前为止,请参阅 my answer here 了解如何设置。)cdn.mydomain.com/fonts/myfont.woff
标头)是 要么 Origin
或 dev.mydomain.com
。www.mydomain.com
在此页面上加载您的字体文件(通过您的 CDN URL)时可以访问该文件,以节省他自己的带宽/托管成本;更不用说网络钓鱼和此类风险了!默认情况下,CloudFront 会缓存任何传入请求的响应。这就是 CDN 的全部意义所在。
但是,第一次(在失效之后)请求来自两个域中的任何一个域对某个文件(例如 junk-cheap.com
),CloudFront 将此文件的响应缓存为 /fonts/myfont.woff
。所以缓存键默认几乎只有路径。
现在,当来自域 B 的请求针对同一个文件时,对象的缓存响应的“允许域”是针对域 A 的,这不匹配导致 CORS 错误。
一个简单的解决方案是告诉 CloudFront 将 { "/fonts/myfont.woff": "<this response object with headers>"}
合并到缓存键中。因此,在上面的示例中,缓存类似于 Origin
。
您可以通过创建一个接受 { ["/fonts/myfont.woff", "Origin: www.mydomain.com"]: <response for www.mydomain.com only>, ... }
标头的新缓存策略来实现此目的:
然后根据您的行为进行设置。
现在,使分发无效并重试!它应该工作。 :)
祝你好运!