CORS Preflight 响应包括 Vary:Origin 和 Access-Control-Max-Age?

Posted

技术标签:

【中文标题】CORS Preflight 响应包括 Vary:Origin 和 Access-Control-Max-Age?【英文标题】:CORS Preflight response includes Vary:Origin and Access-Control-Max-Age? 【发布时间】:2017-08-08 11:04:29 【问题描述】:

我想知道浏览器如何处理包含 Vary: OriginAccess-Control-Max-Age 标头的 CORS Preflight 响应。

此声明来自https://www.w3.org/TR/cors/

希望能够与多个人共享的资源 出处但不统一回应“*”必须在实践中 动态生成 Access-Control-Allow-Origin 标头 响应他们希望允许的每个请求。作为结果, 此类资源的作者应发送 Vary: Origin HTTP 标头或 提供其他适当的控制指令来防止缓存 此类响应,如果跨域重复使用可能会不准确

从这个声明中我了解到 Vary: Origin 会告诉浏览器阻止预检响应的缓存(如果允许来源:* 未使用)

Access-Control-Max-Age 将告诉浏览器将预检响应缓存一段时间。

问题:

    如果两个标头都存在于预检响应中,是否有效?

    如果响应包含两个标头,浏览器如何处理 Preflight 响应?

谢谢!

【问题讨论】:

【参考方案1】:

根据规范要求,Vary: Origin 不会影响CORS-preflight cache 的行为。

如果两个标头都存在于预检响应中,是否有效?

是的,它是有效的。但是,如果存在 Vary 标头,则它不会影响 CORS 预检缓存。

如果响应包含两个标头,浏览器如何处理 Preflight 响应

对于 CORS 预检缓存,浏览器完全忽略 Vary 标头,只使用 Access-Control-Max-Age 标头的值。

我的理解是 Vary: Origin 会告诉浏览器不会缓存预检结果

这不是 Fetch 规范中的要求。

CORS-preflight cache 不是 HTTP 规范中要求涵盖的通用 HTTP 缓存。这是一个特殊的缓存,其行为由 Fetch 规范专门定义。而且 Fetch 规范没有说明任何要求(甚至是间接要求)关于 CORS 预检缓存的行为完全受 Vary 响应标头的影响。

改为the Fetch spec says just this:

max-age 为在给定Access-Control-Max-Ageresponse 的标题列表的情况下提取标题列表值的结果。

这并没有说明在设置 max-age 之前检查 Vary 标头值。

而且由于规范没有明确说明在决定是否填充 CORS 预检缓存时是否/如何使用Vary,因此浏览器不得在执行此操作时使用Vary

如果浏览器在处理 CORS 预检缓存时确实使用了 Vary,那么该浏览器将不符合 CORS 预检缓存的规范要求。

【讨论】:

赞成。 w3 网站说标题 Vary: Origin 将阻止缓存。你能看一下吗。谢谢! 干杯——请注意,您从 w3.org/TR/cors 引用的文本只是一个信息说明——不是规范要求的声明——但无论如何它并没有说明 CORS 预检缓存 & is' t 旨在与 CORS 预检缓存相关。相反,它说“防止缓存此类响应”,这在上下文中仅表示正常的 HTTP 响应。 Vary 标头由 HTTP 规范定义为影响正常 HTTP 缓存的东西,即浏览器都在浏览器依赖的任何网络堆栈中实现,甚至不一定在核心浏览器代码中

以上是关于CORS Preflight 响应包括 Vary:Origin 和 Access-Control-Max-Age?的主要内容,如果未能解决你的问题,请参考以下文章

Express 服务器和 Axios CORS Preflight 响应不成功

为啥没有在 CORS 未命中时设置“Vary: Origin”响应?

对 CORS preflight OPTIONS 请求的响应是 Laravel API 中的 500 Internal Server Error

[CORS][Spring Security] PreFlight 请求未处理

Axios CORS/Preflight 因 Laravel 5.4 API 调用而失败

允许任何 CORS 来源 (*) 时是不是应该设置“Vary: Origin”?