我正在使用 nginx 根据用户位置重定向用户。我只想在查询字符串中增加一个参数,前提是该参数尚未定义 - 如果已定义,则我不想更改它。该参数称为tag
。
这是我的第一次尝试。我希望如果tag=
URL 中的任意位置有字符串,它会落到第二个位置;如果 URL 中有查询字符串但缺少tag
,它会落到第三个位置;如果根本没有查询字符串,它会落到第一个位置。
location / {
return 302 https://$local_site$request_uri?tag=mytag;
}
location /tag=/g {
return 302 https://$local_site$request_uri;
}
location /\?/ {
return 302 http://$local_site$request_uri&tag=mytag;
}
然后我了解到,按位置向下钻取时看不到查询字符串。我还了解到 if 是邪恶的。
有没有不用 if 就能做到这一点的方法?
答案1
nginxlocation
条目仅匹配 URL 的 URI 部分,而不是查询字符串。您可以使用 实现您想要的效果map
。以下内容需要包含在http
块中:
编辑:我原来的回答存在结果 URL 中重复条目的问题tag
。原始解决方案在文章末尾,这是一个修复版本
map $args $newargs {
default $args&tag=mytag;
~ ^(.*)(tag=[^&]+)(.*)$ $1$2$3;
}
然后你将得到以下location
块:
location / {
rewrite (.*) $1?$newargs temporary;
}
我们使用该map
功能定义$newargs
from$args
变量,其中包含 URL 中的查询字符串。默认选项是附加&tag=mytag
到字符串。
如果查询字符串包含tag=something
字符串,那么我们只需将查询字符串复制到新的请求中。
最后,我们将该$newargs
变量用作目标中的查询字符串rewrite
。
这是原始答案:
map $arg_tag $tag {
default $arg_tag;
~ ^$ mytag;
}
然后你将得到以下location
块:
location / {
return 302 https://$local_site$request_uri?tag=$tag;
}
这里我们首先将查询tag
参数映射到$tag
变量。第一行将默认值设置为查询参数值。第二行测试参数是否为空,$mytag
如果为空则设置为值。
然后,您可以$tag
在任何地方使用该变量,并按照您描述的方式映射值。
答案2
基本上if
应该避免,但这并不意味着你不能使用它。
location / {
if ($arg_tag) {
return 302 https://$local_site$request_uri;
}
rewrite ^(.*) https://$local_site$1?tag=mytag;
}