Nginx无跳转URL内部重写添加子域名配置问题求助
问题描述
需求:在不触发跳转的情况下,把example.com/group/abc/的请求内部重写成group.example.com/abc/,同时浏览器地址栏保持example.com/group/abc/不变。
试了下面的Nginx配置,但因为重写的替换字符串以http://开头,直接触发了跳转,不符合要求;把rewrite的flag改成last也没用,想知道配置里漏了啥。
原配置代码:
server { listen *:80; server_name ~^(?<group>.*)\.example\.com$; location / { # Existing settings proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto http; proxy_pass http://localhost:8090; # My addition if ($group = "") { rewrite ^/([^/]+)/(.*)$ http://$1.$host/$2 break; } } }
参考文档说明:
若替换字符串以“http://”“https://”或“$scheme”开头,处理会停止并向客户端返回跳转。
解决方案
你这问题核心出在:用了带http://的替换字符串,不管你用break还是last,Nginx都会直接触发跳转——这是文档明确的规则,改flag没用。要实现内部重写且地址栏不变,不能走外部跳转的思路,得改请求头和代理路径,让后端以为收到的是子域名请求,同时浏览器地址完全不动。
正确的配置得拆成两个server块,分别处理主域名和子域名的请求:
修正后的配置示例
# 专门处理主域名 example.com 的请求 server { listen *:80; server_name example.com; # 匹配 /group/xxx 这类路径 location ~ ^/([^/]+)/(.*)$ { # 把Host头改成子域名,比如 group.example.com proxy_set_header Host $1.example.com; # 其他代理头保持不变 proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto http; # 代理到后端时,路径去掉前面的/group/,直接传/xxx proxy_pass http://localhost:8090/$2$is_args$args; } # 处理主域名下的其他普通请求(如果有需要) location / { proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto http; proxy_pass http://localhost:8090; } } # 原来的子域名处理server块保留,正常处理 group.example.com 的请求 server { listen *:80; server_name ~^(?<group>.*)\.example\.com$; location / { proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto http; proxy_pass http://localhost:8090; } }
关键要点
- 拆分server块:把主域名和子域名的请求分开处理,避免逻辑混乱。
- 修改Host头:当主域名收到
/group/abc/请求时,提取group部分,把请求的Host头改成group.example.com,让后端服务识别为子域名的请求。 - 调整代理路径:代理到后端时,把路径改成去掉
/group/后的/abc/,确保后端收到正确的路径。 - 全程无跳转:整个过程都是Nginx内部的请求改写,不会给浏览器返回跳转响应,地址栏完全保持原来的
example.com/group/abc/。
内容的提问来源于stack exchange,提问作者Naman Gala
相关产品推荐
相关产品推荐

