我正在尝试编写一个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。“访问-控制-允许-原产地”标头的值“http://示例.com”与所提供的源不相等。因此,原产地'http:// admin .示例. com‘是不允许访问的。
据我所知,这是因为浏览器用它附带的头缓存原始请求,而现在它拒绝了我,即使来自服务器的另一个请求也会允许它。证据是,如果我检查禁用缓存在Chrome开发工具,那么这个问题永远不会发生。
我该如何解决这个问题?是否可以在一个配置中完成多个域+ ssl/http,还是有必要根据所请求的域和协议将其拆分?
(很抱歉在我的例子中出现了可怕的空格,显然StackOverflow认为我只是在写示例时试图发布链接)
发布于 2017-09-06 05:39:22
如果添加Vary响应标头的值为Origin,则会导致任何浏览器跳过缓存,并在Origin请求头的值与缓存的请求的Origin值不同时发出新的网络请求。
见HTTP规范的相关部分。因此,您可以更新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";
}您可以在响应标头中阅读更多内容。
Varyheader决定如何匹配未来的请求头,以决定是否可以使用缓存的响应,而不是从源服务器请求一个新的响应。服务器使用它来指示在内容协商算法中选择资源表示时使用的标头。
…在MDN Access-Control-Allow-Origin文章的CORS和缓存部分:
如果服务器发送一个具有显式来源的
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。 但是,如果在同一场景中使用Vary: Origin,它将导致用户代理获取包含Access-Control-Allow-Origin的响应,而不是使用之前缺少Access-Control-Allow-Origin的非CORS请求的缓存响应。
https://stackoverflow.com/questions/46063304
复制相似问题