http - 跨站点缓存 Access-Control-Allow-Origin 值

标签 http nginx cors browser-cache http-caching

我正在尝试编写一个 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 时,我会遇到这样的问题

(index):1 XMLHttpRequest cannot load http://origin.example.com/js/data-lib/currency.json. The 'Access-Control-Allow-Origin' header has a value 'http:// example . com' that is not equal to the supplied origin. Origin 'http:// admin . example . com' is therefore not allowed access.

据我所知,这是因为浏览器缓存了带有 header 的原始请求,现在它拒绝了我,即使来自服务器的另一个请求允许它。证据是,如果我在 Chrome 开发者工具中选中禁用缓存,那么问题就不会发生。

我该如何解决这个问题?是否可以在一个配置中执行多个域 + ssl/http,或者是否有必要根据请求的域和协议(protocol)将其拆分?

(对于我的示例中可怕的空间感到抱歉,显然 StackOverflow 认为我只是在编写示例时试图发布链接)

最佳答案

如果您添加值为 OriginVary 响应 header ,这应该会导致任何浏览器跳过其缓存并在Origin 请求 header 的值与其缓存的请求的 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 中阅读更多内容.

The Vary HTTP response header determines how to match future request headers to decide whether a cached response can be used rather than requesting a fresh one from the origin server. It is used by the server to indicate which headers it used when selecting a representation of a resource in a content negotiation algorithm.

…在 MDN Access-Control-Allow-Origin 文章中的 CORS and caching部分:

If the server sends a response with an Access-Control-Allow-Origin value that is an explicit origin (rather than the "*" wildcard), then the response should also include a Vary response header with the value Origin — to indicate to browsers that server responses can differ based on the value of the Origin request header.

……在 the Fetch spec itself 中:

If your requirements are more complicated than setting Access-Control-Allow-Origin to * or a static origin, use the Vary: Origin response header.

If Vary is not used and a server is configured to send Access-Control-Allow-Origin for a certain resource only in response to a CORS request: When a user agent receives a response to a non-CORS request for that resource, the response will lack Access-Control-Allow-Origin and the user agent will cache that response. If the user agent then encounters a CORS request for the resource, it will use that cached response from the previous non-CORS request — without Access-Control-Allow-Origin.

But if Vary: Origin is used in the same scenario, it will cause the user agent to fetch a response that includes Access-Control-Allow-Origin, rather than using the cached response from the previous non-CORS request lacking Access-Control-Allow-Origin

关于http - 跨站点缓存 Access-Control-Allow-Origin 值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46063304/

相关文章:

ajax - Angular 2 : How to make several GET requests at once

javascript - 使用 AJAX/jQuery 在网络摄像机上进行 HTTP 基本授权

Java URL 连接 : how can I find out the size of a web file?

node.js - Node+Express+NGINX 应用程序返回 localhost 而不是域

google-maps-api-3 - 谷歌地图 - 跨域请求被阻止 : The Same Origin Policy disallows reading the remote resource at

http - 使用分块传输编码时的 Grails 多个请求

Nginx 提供静态文件并收到 403 禁止

F# WebApi Cors 不起作用

javascript - 跨域 REST POST 进行预检但不跟进

php - NGINX/PHP - 无法通过 php 脚本提供 jpeg