Nginx如何匹配URL的version参数以服务对应版本号目录
配置不生效的核心原因
- Nginx的
location匹配规则仅作用于请求的URI路径部分(即URL中?之前的内容),查询字符串不会参与location匹配,因此你写的^\?version=xxx规则永远不会被触发。 - 你的正则表达式仅捕获了1个分组,配置中却使用了
$2变量,属于语法错误。
实现方案
该场景完全可实现,两种常用方案如下:
方案1:直接在location中校验(无需map)
适合规则简单的场景,内置格式校验避免路径遍历风险:
server { listen 80; server_name test; location / { # 校验version参数是否为三段数字格式 set $version_root /var/www/test/htdocs; if ($arg_version ~ ^\d+\.\d+\.\d+$) { set $temp_root /var/www/test/htdocs/v$arg_version; # 仅对应版本目录存在时才生效 if (-d $temp_root) { set $version_root $temp_root; } } root $version_root; try_files $uri $uri/ =404; } }
方案2:使用map配置(更易维护)
适合多规则、多版本的场景,map需定义在http块中:
# 此段配置需放在nginx.conf的http块内,所有server块外层 map $arg_version $version_dir { # 匹配合法三段数字版本号,返回对应v开头的目录名 ~^(\d+\.\d+\.\d+)$ v$1; # 自定义默认版本,无合法version参数时生效 default v12.1.0; } server { listen 80; server_name test; root /var/www/test/htdocs/$version_dir; location / { try_files $uri $uri/ =404; } }
注意事项
- 如果要禁止用户直接访问
/v12.1.0/xxx这类路径绕过参数判断,可增加如下规则:
location ~ ^/v\d+\.\d+\.\d+/ { return 403; }
- 配置修改完成后需执行
nginx -t校验语法,校验通过后执行nginx -s reload生效。
内容的提问来源于stack exchange,提问作者WhoAmI
相关产品推荐
相关产品推荐

