我有以下情况:
在我的网站上,javascript 设置了一个包含生成标记的相关信息的 cookie。
因此,我希望 Varnish 针对所述 cookie 的每个值分别缓存每个页面。
我找到的所有文档都表明,如果存在任何 cookie,Varnish 将不会缓存,并解释了如何在 Varnish 预处理中删除 cookie。
这显然不是我想要的,我想要缓存,即使存在某个 cookie,但要针对 cookie 的每个值分别进行缓存。
有什么方法可以实现这个吗?
答案1
这个有可能
例如:
sub vcl_recv {
set req.http.X-COOKIEHASH = "";
if (req.http.Cookie ~ "COOKIEHASH=") {
set req.http.X-COOKIEHASH = regsub(req.http.Cookie,"^.*?COOKIEHASH=([^;]*);*.*$", "\1");
/* to prevent default action when cookies are present */
/* this is shortcut - you should adjust this to your VCL logic */
return (lookup);
}
}
sub vcl_hash {
hash_data(req.http.X-COOKIEHASH);
}
sub vcl_miss {
unset bereq.http.X-COOKIEHASH;
}
sub vcl_pass {
unset bereq.http.X-COOKIEHASH;
}
在 vcl_recv() 中,我们提取 cookie 的值(名为 COOKIEHASH),并在 vcl_hash() 中将该值添加到哈希函数中。
这是一个 cookie 的示例。但添加更多 cookie 名称很容易。您还必须记住处理其他 cookie(丢弃或忽略它们)。
答案2
这开始是对 RJS 的回答的评论 - 但是它有点长......
IIRC(不要用 Varnish 做很多事情)你需要指定全部vcl_hash 中唯一性的决定因素——因此 RJS 的答案可能是错误的——事实上手册中的示例明确使用 URL 以及其他指标。
我认为 RJS 的方式也存在一些问题提取 cookie假设cookie值在req.http.X-COOKIEHASH中,则解决方案为:
sub vcl_hash {
hash_data(req.url);
hash_data(req.http.X-COOKIEHASH);
}
这样做的结果是 Varnish 将开始缓存不随 cookie 变化的内容副本 - 因此您可能希望排除静态内容 URL 使用 cookie 来确定哈希值。
然而,这无助于解决其他缓存的问题——无论是中间缓存还是浏览器缓存。内容应使用 Vary: Cookie 标头提供。另请参阅讨论这里