使用正则配置Nginx时出现过多重定向问题求助
问题描述
单项目配置Swagger时Nginx运行正常:
location /project1/v2 { absolute_redirect off; alias /project1/v2; expires 1d; location ~* \.(?:json|yml|yaml)$ { # SWAGGER_ROOT expires -1; include /etc/nginx/templates/cors.conf; } include /etc/nginx/templates/cors.conf; } location /project1{ set $args $args&url=http://localhost/project1/v2/swagger.json; absolute_redirect off; alias /usr/share/nginx/html/; expires 1d; include /etc/nginx/templates/cors.conf; }
但改用正则匹配多项目(project1、project2)时,出现循环重定向,URL会变成重复叠加index.html和url参数的异常情况:
http://localhost/project1/index.html/index.html/.../?&url=http://localhost/project1/v2/swagger.json&url=...
对应的多项目配置如下:
location ~ ^/(project1|project2)/v2 { absolute_redirect off; alias /$1/v2; expires 1d; location ~* \.(?:json|yml|yaml)$ { # SWAGGER_ROOT expires -1; include /etc/nginx/templates/cors.conf; } include /etc/nginx/templates/cors.conf; } location ~ ^/(project1|project2) { set $args $args&url=http://localhost/$1/v2/swagger.json; absolute_redirect off; alias /usr/share/nginx/html/; expires 1d; include /etc/nginx/templates/cors.conf; }
错误原因
- 正则匹配范围重叠:第二个正则
~ ^/(project1|project2)会匹配所有以project1/project2开头的请求,包括已经被第一个/v2location处理的请求,导致请求被重复拦截处理。 - index自动重定向循环:访问
/project1时,Nginx会自动查找index.html并发起重定向到/project1/index.html,而这个URL又会被第二个正则location匹配,再次执行set $args添加url参数;同时alias到静态目录后,又会触发index查找逻辑,陷入循环,最终导致路径和参数不断重复叠加。
修正后的配置
需要明确区分两个location的匹配优先级,同时避免index重定向循环,以下是两种可行的修正方案:
方案一:分路径精确匹配
# 优先匹配/v2路径,用^~提升优先级,避免被后续正则匹配 location ^~ /project1/v2 { absolute_redirect off; alias /project1/v2; expires 1d; location ~* \.(?:json|yml|yaml)$ { expires -1; include /etc/nginx/templates/cors.conf; } include /etc/nginx/templates/cors.conf; } location ^~ /project2/v2 { absolute_redirect off; alias /project2/v2; expires 1d; location ~* \.(?:json|yml|yaml)$ { expires -1; include /etc/nginx/templates/cors.conf; } include /etc/nginx/templates/cors.conf; } # 仅匹配项目根路径(/project1或/project2),直接指定index避免重定向 location ~ ^/(project1|project2)$ { set $args $args&url=http://localhost/$1/v2/swagger.json; absolute_redirect off; alias /usr/share/nginx/html/; index index.html; expires 1d; include /etc/nginx/templates/cors.conf; } # 匹配项目下的静态资源,排除/v2路径 location ~ ^/(project1|project2)/(?!v2) { absolute_redirect off; alias /usr/share/nginx/html/; expires 1d; include /etc/nginx/templates/cors.conf; }
方案二:正则统一处理
# 优先匹配/v2路径,正则加^~提升优先级 location ~ ^/(project1|project2)/v2 { absolute_redirect off; alias /$1/v2; expires 1d; location ~* \.(?:json|yml|yaml)$ { expires -1; include /etc/nginx/templates/cors.conf; } include /etc/nginx/templates/cors.conf; } # 仅匹配项目根路径(/project1或/project2) location ~ ^/(project1|project2)$ { set $args $args&url=http://localhost/$1/v2/swagger.json; absolute_redirect off; alias /usr/share/nginx/html/; index index.html; expires 1d; include /etc/nginx/templates/cors.conf; } # 匹配项目下的静态资源,排除/v2路径并正确映射文件 location ~ ^/(project1|project2)/(?!v2)(.*)$ { absolute_redirect off; alias /usr/share/nginx/html/$2; expires 1d; include /etc/nginx/templates/cors.conf; }
内容的提问来源于stack exchange,提问作者Hasan Can Saral
相关产品推荐
相关产品推荐

