跨站点缓存访问-控制-允许-原始值 [英] Caching of Access-Control-Allow-Origin value cross-site
问题描述
我正在尝试编写一个nginx配置,它将同时处理http和https上的两个站点,只要客户端从不访问这两个站点,它似乎就可以工作,但如果访问,就会出现缓存/跨站点问题。
# Allow cross origin
location ~* .(eot|svg|ttf|woff|woff2|json)$ {
if ($http_origin ~* (https?://(admin.)?example.com(:[0-9]+)?)) {
add_header 'Access-Control-Allow-Origin' "$http_origin";
}
}
因此,如果我加载Example.com,一切都会正常工作,但当我加载admin.example.com时,我会遇到这样的问题
(索引):1个XMLHttpRequest无法加载 http://origin.example.com/js/data-lib/currency.json。"Access-Control-Allow-Origin"标头的值""http://Example.com""不等于提供的源。""因此不允许访问来源‘http://admin.Example.com’。
据我所知,这是因为浏览器缓存了原始请求和它附带的头,现在它拒绝我,即使来自服务器的另一个请求允许它这样做。证据是,如果我检查Chrome开发人员工具中的禁用缓存,那么这个问题永远不会发生。
如何解决此问题?是否可以在一个配置中完成多个域+SSL/http,或者是否有必要根据请求的域和协议进行拆分?
(很抱歉我的示例中有可怕的空格,显然StackOverflow认为我只是在编写示例时试图发布链接)
推荐答案
如果您使用值Origin
添加Vary
响应标头,则当Origin
请求标头的值与其缓存的请求的Origin
值不同时,应该会导致任何浏览器跳过其缓存并发出新的网络请求。
参见the relevant part of the HTTP spec。因此,您可以更新您的nginx配置以执行此操作:
# Allow cross origin
location ~* .(eot|svg|ttf|woff|woff2|json)$ {
if ($http_origin ~* (https?://(admin.)?example.com(:[0-9]+)?)) {
add_header 'Access-Control-Allow-Origin' "$http_origin";
}
add_header 'Vary' "Origin";
}
您可以在the MDN article on the Vary
response header中阅读更多内容。
Vary
HTTP响应头确定如何匹配将来的请求
标头来决定是否可以使用缓存的响应,而不是
从源站请求一个新的。它由
服务器来指示它在选择
内容协商算法中资源的表示形式。
…并在MDNAccess-Control-Allow-Origin
文章的CORS and caching部分中:
如果服务器发送的响应具有显式来源的
Access-Control-Allow-Origin
值(而不是通配符),则该响应还应包括值为Origin
的Vary
响应标头,以向浏览器指示服务器响应可能会根据Origin
请求标头的值而有所不同。
如果您的需求比设置Access-Control-Allow-Origin
若要*
或静态来源,请使用Vary: Origin
响应标头。如果
Vary
未使用,并且服务器配置为仅响应CORS请求发送特定资源的Access-Control-Allow-Origin
:当用户代理接收到对该资源的非CORS请求的响应时,该响应将缺少Access-Control-Allow-Origin
,并且用户代理将缓存该响应。如果用户代理随后遇到针对该资源的CORS请求,则它将使用来自前一个非CORS请求的缓存响应-不需要Access-Control-Allow-Origin
。但如果在同一场景中使用
的前一个非CORS请求的缓存响应Vary: Origin
,则会导致用户代理获取包含Access-Control-Allow-Origin
的响应,而不是使用缺少Access-Control-Allow-Origin
这篇关于跨站点缓存访问-控制-允许-原始值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!