如何在清漆中保留特定的查询参数

How to keep specific query parameters in varnish

我的问题可能有点奇怪。通常您希望从 url 中剥离特定的查询参数以缓存在 Varnish 中。但我想做相反的事情。这是使用某些查询参数(如 utm_source 等)重定向所必需的

我有一组查询参数不需要剥离,其余的可以剥离。

经过一段时间的反复试验,我找到了一种方法。

首先,我们在 sub vcl_recv 中使用此代码去除任何营销查询参数以清理 URL:

# Store original url in temporary header
set req.http.X-Original-Url = req.url;

# Strip all marketing get parameters
if(req.url ~ "(\?|&)(gclid|cx|ie|cof|siteurl|zanpid|origin|utm_[a-z]+|mr:[A-z]+)=") {
    set req.url = regsuball(req.url, "(gclid|cx|ie|cof|siteurl|zanpid|origin|utm_[a-z]+|mr:[A-z]+)=[%.-_A-z0-9]+&?", "");
}
set req.url = regsub(req.url, "(\?&|\?|&)$", "");

接下来在 sub vcl_fetch 中,我们使用此代码在重定向后重新附加营销查询参数,但去除所有其他查询参数。

if (beresp.status == 301 || beresp.status == 302) {
    set beresp.http.location = beresp.http.location + "?" + regsub(req.http.X-Original-Url, ".*\?(.*)", "");
    set beresp.http.location = regsuball(beresp.http.location, "([&|?](?!gclid|cx|ie|cof|siteurl|zanpid|origin|utm_[a-z]+|mr:[A-z]+)[\w\d]+=([%.-_A-z0-9]+)?)", "");  # Comment or remove this line to keep the original query parameters after redirect
    set beresp.http.location = regsub(beresp.http.location, "(\?&|\?|&)$", "");
    return (hit_for_pass);
}

我还制作了一个快速 enable/disable 变体,因此人们可以 enable/disable 剥离所有非营销查询参数。请参阅 sub vcl_fetch 代码中的注释

只是为了使用最新版本的 Varnish 对此进行更新(例如 sub vcl_fetch 已重命名)。以下对我们有用:

vcl_recv中:

# Store original url in temporary header
set req.http.X-Original-Url = req.url;

# strip out query string
set req.url = regsub(req.url, "\?.*$", "");

vcl_backend_response中:

# restore URL params after a redirect
if (resp.status == 301 || resp.status == 302) {
  set resp.http.location = resp.http.location + "?" + regsuball(req.http.X-Original-Url, "(^.*(?=\?)|[?&](?!header1|header2)\w+=[^&]*)", "");
  # strip occurrences of `?&` after removing params
  set resp.http.location = regsub(resp.http.location, "(\?&|\?\?)", "?");
  # some more cleanup (empty `?` or `&` at end)
  set resp.http.location = regsub(resp.http.location, "(\?&|\?|&)$", "");
}

在哪里

  • ^.*(?=\?) 仅保留查询字符串 "everything that comes after the ?"(例如 ?key1=value1&key2=value2
  • [?&](?!header1|header2)\w+ 匹配不匹配 header1header2
  • 的键名
  • =[^&]* 匹配 = 字符和 value 直到 &
  • 的下一次出现

以下regsubs用于清理。希望他们能自我解释。