Nginx实现乱序匹配路径中的多个query参数

本文讲述了如何在Nginx反向代理配置中利用set和if条件判断,确保query参数foo和bar的存在,如果缺失则返回404。通过设置变量并结合逻辑运算,解决不支持逻辑与或非的限制。

最近项目想实现在反向代理层判断query参数,比如强制要求必须存在foo和bar参数,如果不满足条件就404
最开始想通过正则来进行多字符串乱序匹配
在网上搜了好久,唯一一个几乎能够满足要求的,发现在Nginx中无法使用。
最终还是需要使用if进行条件判断
https://stackoverflow.com/a/11310817/7151777
但是Nginx语法竟然不支持if条件的逻辑与或非,而且没有else
例如如下写法就会报错

server {
    ...
    
    location ~ /xxx {
        if ( $arg_foo != '' && $arg_bar != '' ) {
            return 200;
        }
    }
}
>>> nginx -t
nginx: [emerg] invalid condition "$arg_foo" in /etc/nginx/sites-enabled/default:4
nginx: configuration file /etc/nginx/nginx.conf test failed

所以就只能通过标记变量来实现
如下所示,在条件都满足后,变量a会变为11,最后返回200

server {
    ...
    
    location ~ /xxx {
        set $a 0;
        if ( $arg_foo != '') {
            set $a 1;
        }
        if ( $arg_bar != '') {
            set $a 1$a;
        }
        if ( $a = 11 ) {
            return 200 $a;
        }
    }
}

参考:
https://blog.youkuaiyun.com/abc86319253/article/details/49763267
https://ofstack.com/Nginx/14906/examples-of-if–and–or-statement-usage-in-nginx.html

Nginx 中,虽然 `location` 指令本身是用于单一路径匹配的,但可以通过多种方式实现多个路径匹配需求。以下是一些常见且有效的配置方法: ### 1. 使用多个 `location` 块 最直接的方法是为每个需要匹配路径定义一个独立的 `location` 块。这种方式适用于路径数量有限且需要分别处理的情况。例如: ```nginx location /path1 { # 处理 /path1 的请求 } location /path2 { # 处理 /path2 的请求 } ``` 通过这种方式,可以分别对不同的路径应用不同的配置逻辑[^1]。 ### 2. 使用正则表达式匹配多个路径 如果多个路径具有共同的模式,可以使用正则表达式来匹配它们。正则表达式匹配使用 `~`(区分大小写)或 `~*`(不区分大小写)修饰符。例如: ```nginx location ~ ^/(path1|path2) { # 处理 /path1 和 /path2 的请求 } ``` 该配置可以匹配 `/path1` 和 `/path2` 路径,以及它们的子路径(如 `/path1/sub` 和 `/path2/sub`)。[^4] ### 3. 使用前缀匹配与最长匹配规则 Nginx匹配 `location` 时遵循最长匹配原则。如果多个 `location` 块都能匹配请求的 URI,Nginx 会选择匹配长度最长的那个。例如: ```nginx location /images { # 匹配所有以 /images 开头的 URI } location /images/aa { # 匹配 /images/aa 及其子路径 } ``` 在这种情况下,对于请求 `/images/aa/test.jpg`,Nginx 会选择匹配 `/images/aa`,因为它是更具体的路径[^4]。 ### 4. 使用 `alias` 和 `root` 的区别 当配置静态资源路径时,`alias` 和 `root` 的行为有所不同。`alias` 会将匹配路径部分替换为目标路径,而 `root` 会将匹配路径附加到目标路径之后。例如: ```nginx location /user { alias /home/html; # 请求 /user/info/a.txt 会映射到 /home/html/info/a.txt } location /user { root /home/html; # 请求 /user/info/a.txt 会映射到 /home/html/user/info/a.txt } ``` 通过合理使用 `alias` 和 `root`,可以更灵活地控制资源的映射方式[^3]。 ### 5. 使用 `try_files` 实现路径匹配 `try_files` 指令可以尝试多个文件路径,并返回第一个存在的文件。这在需要匹配多个可能的路径时非常有用。例如: ```nginx location / { try_files $uri $uri/ /backup.html; } ``` 此配置会尝试匹配请求的 URI、URI 加斜杠(目录)以及最后的后备文件 `backup.html`。[^2] ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值