仅当尚未定义时才向 nginx 重定向添加参数

仅当尚未定义时才向 nginx 重定向添加参数

我正在使用 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功能定义$newargsfrom$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;
}

相关内容