所以,这就是我的难题!在过去的三天里,我一直试图让Cloudfront与我的nginx服务器很好地玩耍...阅读了无数的StackOverflow帖子和博客文章......搜索了互联网,我仍然遇到有关跨域访问策略的问题它涉及Cloudfront服务字体。我将发布我的完整设置,希望有更多专业知识的人可以帮我弄清楚发生了什么。将来,我希望这篇文章能够为面临类似问题的许多其他人提供服务。 这里......
我有一个带有以下服务器块配置的nginx webserver。 (...为简洁而截断)
server {
server_name example.com www.example.com;
root /var/www/example.com/html;
index index.html index.htm;
location / {
try_files $uri $uri/ =404;
}
location /assets {
autoindex on;
}
# Media
location ~* \.(jpe?g|gif|png|ico|cur|gz|svgz?|mp4|ogg|ogv|webm|htc|webp)$ {
expires 1M;
access_log off;
add_header Cache-Control public;
}
# Fonts
location ~* \.(eot|ttf|woff|woff2|svg)$ {
expires 365d;
access_log off;
add_header Cache-Control public;
add_header Access-Control-Allow-Origin example.com;
// Have also tried setting the "Access-Control-Allow-Origin" header to "*", but I'd prefer not to do this for security reasons.
}
}
仅供参考:我想要服务并卸载到CloudFront的所有网站文件都在我的虚拟主机的/assets
目录中。 (即http://example.com/assets/.。)
我使用以下设置创建了一个新的CloudFront分配:
注意:我没有使用S3来托管我的网站文件和资产。
我的区域文件的一部分......
example.com. 1800 IN A 12.34.567.890 //faked IP here for privacy reasons
www.example.com. 1800 IN CNAME example.com.
static.example.com. 1800 IN CNAME kg72kgf83nhfy3.cloudfront.net. //faked CloudFront dist. domain name here for privacy reasons
因此,CloudFront会处理和部署我的发行版,并且我假设从我的 ' / assets /..' 中提取资产网络目录。所有src
,href
和CSS url()
引用都指向我当前的HTML和CSS文档中的 http://static.example.com ,包括所有font-face
引用。部署分发后,我在浏览器中点击了我的网站 http://example.com 。
似乎所有静态网站资产都是从CloudFront正确提供的,具有我的nginx配置中定义的适当缓存标头... EXCEPT ... webfonts。我在浏览器控制台中丢失了页面上的字体和跨域访问策略错误消息。
图片,供参考(在ping我的服务器时):
curl -I "http://example.com/assets/images/image1.png"
HTTP/1.1 200 OK
Server: nginx/1.6.3
Date: Sun, 15 May 2016 02:09:25 GMT
Content-Type: image/png
Content-Length: 194665
Last-Modified: Sun, 15 May 2016 01:52:35 GMT
Connection: keep-alive
ETag: "5737d663-2f869"
Expires: Tue, 14 Jun 2016 02:09:25 GMT
Cache-Control: max-age=2592000
Cache-Control: public
Accept-Ranges: bytes
字体(在ping我的服务器时):
curl -I "http://example.com/assets/fonts/webfont.woff"
HTTP/1.1 200 OK
Server: nginx/1.6.3
Date: Sun, 15 May 2016 02:10:29 GMT
Content-Type: application/font-woff
Content-Length: 8752
Last-Modified: Sun, 15 May 2016 01:51:55 GMT
Connection: keep-alive
Vary: Accept-Encoding
ETag: "5737d63b-2230"
Expires: Mon, 15 May 2017 02:10:29 GMT
Cache-Control: max-age=31536000
Cache-Control: public
Access-Control-Allow-Origin: example.com
Accept-Ranges: bytes
相同的图片(从CloudFront请求时):
curl -I "http://static.example.com/assets/images/image1.png"
HTTP/1.1 200 OK
Content-Type: image/png
Content-Length: 194665
Connection: keep-alive
Server: nginx/1.6.3
Date: Sun, 15 May 2016 02:39:16 GMT
Last-Modified: Sun, 15 May 2016 01:52:35 GMT
ETag: "5737d663-2f869"
Expires: Tue, 14 Jun 2016 02:39:16 GMT
Cache-Control: max-age=2592000
Cache-Control: public
Accept-Ranges: bytes
X-Cache: Miss from cloudfront
Via: 1.1 lots_of_random_characters_i_dont_know_if_should_share_here.cloudfront.net (CloudFront)
X-Amz-Cf-Id: lSM1plINYENbYycBn424LJ2wdtDhS3CpqAFiDSoxQDEctP_WM09bUQ==
相同字体(从CloudFront请求时):
curl -I "http://static.example.com/assets/fonts/webfont.woff"
HTTP/1.1 200 OK
Content-Type: application/font-woff
Content-Length: 8752
Connection: keep-alive
Server: nginx/1.6.3
Date: Sun, 15 May 2016 02:41:00 GMT
Last-Modified: Sun, 15 May 2016 01:51:55 GMT
ETag: "5737d63b-2230"
Expires: Mon, 15 May 2017 02:41:00 GMT
Cache-Control: max-age=31536000
Cache-Control: public
Access-Control-Allow-Origin: example.com
Accept-Ranges: bytes
Vary: Accept-Encoding
X-Cache: Miss from cloudfront
Via: 1.1 lots_of_random_characters_i_dont_know_if_should_share_here.cloudfront.net (CloudFront)
X-Amz-Cf-Id: vNfiyurS8pjosofnpLNSrnZuaGFg0V4xIs4ySCm05NKDMZ_PozhuOg==
将我的网站加载到 http://example.com ,一切似乎都有效(即图片)除了网络字体。检查浏览器控制台会为每种字体输出以下消息:
源自' http://static.example.com'的字体已被跨源资源共享策略阻止加载:“访问控制 - 允许 - 来源”'标头包含无效值' example.com'。起源' http://example.com'因此不允许访问。
那么,任何人都有任何想法?我会非常欣赏帮助/输入。我是一个年轻的网络开发者,只是想学习。
谢谢! :)
-Kyle
脚注:
//static.example.com/assets/images/image.png?622c6911
),以使CloudFront缓存无效。这样我就不必总是通过更改名称重新上传新资产......我可以简单地控制HTML中的失效,并在我希望CloudFront从我的网络服务器请求该文件的最新版本时,将新的查询字符串附加到资产原点。答案 0 :(得分:3)
解释如下:
' Access-Control-Allow-Origin'标头包含无效值' example.com'。起源' http://example.com'因此不允许访问。
原点是http://example.com
...不是example.com
。您的响应标头的值不正确。根据定义,原点是scheme + hostname + port(在标准端口上为http和https省略了隐式端口80和443)。
当请求不受跨域规则约束时(例如图像的情况),浏览器会忽略Web服务器上的错误配置。对于字体,您要点击此墙,因为该值格式不正确。
add_header Access-Control-Allow-Origin example.com;
这是你问题的根源。您需要使用Origin:
标头中的浏览器发送的相同来源进行响应,假设该来源确实有效且应该被允许。我不是nginx专家,根据this answer,您可以使用正则表达式验证传入的来源,并相应地设置响应:
if ($http_origin ~* "^https?://.*example\.com$" ) {
add_header Access-Control-Allow-Origin $http_origin;
}
不熟悉nginx正则表达式的怪癖,我有点宽容,但你明白了。
在此之前,我们需要修复CloudFront缓存行为。
转发标题:白名单
访问控制允许来源
这不是一个请求标题......它是一个响应标题,因此将其列入白名单实际上并没有做任何事情。
您需要将Origin
标头列入白名单,以便CloudFront将其转发到Web服务器,以便服务器可以使用Access-Control-Allow-Origin:
中的相同值进行响应,如图所示上方。
Access-Control-Request-Headers
和Access-Control-Request-Method
也应该列入白名单,但对于GET
请求,我不知道它们会很重要。
除了OPTIONS
和GET
之外,您还应修改允许的方法以包含HEAD
。
奖金材料:
我的计划是将散列查询字符串附加到每个文件的末尾(即//static.example.com/assets/images/image.png?622c6911),以使CloudFront缓存无效。
在这种情况下,您需要将Forward Query Strings
设置为Yes
。
CloudFront根据对象实际发送到服务器的内容来缓存对象。如果查询字符串未转发到源,则附加查询字符串将仅使浏览器缓存而非CloudFront缓存无效。是的,即使您的服务器不想要或不需要查询字符串,如果查询字符串旨在用于缓存破坏CloudFront,您也需要启用此功能。这就是为什么不转发它们"改善缓存。"它将得到改善"在确定是否已有对象的缓存版本时,CloudFront完全忽略它们。
另请注意,Via
标头不包含敏感信息,X-Amz-Cf-Id
也不包含。