我有以下情况:
在我的网站上,javascript设置了一个包含用于生成标记的相关信息的cookie。
因此,我希望Varnish为每个cookie分别caching每个页面。
我发现的所有文档都说如果存在任何cookie,varnish将不会caching,并解释如何在varnish预处理中删除cookie。
这显然不是我想要的,我想要caching,即使某个cookie存在,但是分别为每个cookie的值。
任何方式来实现这一目标?
这个有可能
例如:
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(丢弃或忽略)。
这开始作为对RJS的答案的评论 – 但它有点长…
IIRC(不要用Varnish做很多事情)你需要在vcl_hash中指定唯一性的所有决定因素 – 因此RJS的答案可能是错误的 – 实际上手册中的例子明确地使用了URL以及其他指标。
我认为RJS 提取cookie的方式也存在一些问题。 假设cookie值在req.http.X-COOKIEHASH中,解决scheme是:
sub vcl_hash { hash_data(req.url); hash_data(req.http.X-COOKIEHASH); }
这样做的结果是Varnish将开始caching与Cookie不同的内容副本 – 因此,您可能希望排除使用Cookie的静态内容URL来确定哈希值。
但是,这并不能解决其他caching(中间和浏览器)的问题。 内容应该用一个Vary:Cookie标题来提供。 另请参阅此处的讨论