缓存 Access-Control-Allow-Origin 值 cross-site
Caching of Access-Control-Allow-Origin value cross-site
我正在尝试编写一个 nginx 配置来处理 http 和 https 上的两个站点,只要客户端从不访问这两个站点,它似乎就可以工作,但如果他们这样做,就会出现 caching/cross-site 问题.
# 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,一切正常,但是当我加载管理员时。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,或者是否有必要根据请求的域和协议将其拆分?
(抱歉,我的示例中出现了可怕的空格,显然 Whosebug 认为我在编写示例时正在尝试 post 链接)
如果您添加 Vary
响应 header 和值 Origin
,这应该会导致任何浏览器跳过其缓存并在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.
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
我正在尝试编写一个 nginx 配置来处理 http 和 https 上的两个站点,只要客户端从不访问这两个站点,它似乎就可以工作,但如果他们这样做,就会出现 caching/cross-site 问题.
# 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,一切正常,但是当我加载管理员时。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,或者是否有必要根据请求的域和协议将其拆分?
(抱歉,我的示例中出现了可怕的空格,显然 Whosebug 认为我在编写示例时正在尝试 post 链接)
如果您添加 Vary
响应 header 和值 Origin
,这应该会导致任何浏览器跳过其缓存并在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 aVary
response header with the valueOrigin
— to indicate to browsers that server responses can differ based on the value of theOrigin
request header.
If your requirements are more complicated than setting
Access-Control-Allow-Origin
to*
or a static origin, use theVary: Origin
response header.If
Vary
is not used and a server is configured to sendAccess-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 lackAccess-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 — withoutAccess-Control-Allow-Origin
.But if
Vary: Origin
is used in the same scenario, it will cause the user agent to fetch a response that includesAccess-Control-Allow-Origin
, rather than using the cached response from the previous non-CORS request lackingAccess-Control-Allow-Origin