Nginx rewrite规则失效致404问题求助(附配置)
我来帮你搞定这个Nginx配置的问题!你遇到的404错误,核心原因是当前的rewrite规则没有正确移除/list前缀,导致请求最终还是带着/list路径传到了list.example.com:89,而后端服务没有对应的路径,所以返回了404。
下面给你两种修正方案,选一种适合你的就行:
方案一:移除冗余rewrite,直接用proxy_pass路径映射(推荐)
这是最简洁高效的方式,不需要额外的rewrite规则,Nginx会自动帮你处理路径替换:
server { listen 80; listen 443 ssl; server_name www.example.com; keepalive_timeout 70; ssl_certificate cert\www.example.com_public.crt; ssl_certificate_key cert\www.example.com.key; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers HIGH:!aNULL:!MD5; charset utf-8; access_log logs/example_com.host.access.log; # 处理/list开头的请求,自动移除/list前缀转发到后端 location /list { proxy_pass http://list.example.com:89/; } # 处理根路径及其他未匹配的请求 location / { proxy_pass http://www.example.com:81; } }
为什么这个能行?
当请求http://www.example.com/list/findcontent.action?id=6进来时,Nginx匹配到location /list后,会自动把请求URI中/list的部分替换成proxy_pass结尾的/,最终转发到http://list.example.com:89/findcontent.action?id=6,完全符合你的需求。
方案二:修正rewrite规则(如果你偏好使用rewrite)
如果你一定要保留rewrite逻辑,需要调整正则表达式来完整捕获/list后的路径内容,确保替换正确:
server { # 其他配置保持不变... location /list { # 捕获/list后的所有内容,替换为捕获到的部分 rewrite ^/list(.*)$ $1 break; # 这里proxy_pass后面不要加/,避免路径重复拼接 proxy_pass http://list.example.com:89; } location / { proxy_pass http://www.example.com:81; } }
原理说明:
正则^/list(.*)$会匹配整个以/list开头的URI,把/list后面的所有内容(包括/findcontent.action?id=6)捕获到变量$1中,替换后URI就变成了/findcontent.action?id=6,再通过proxy_pass转发到后端,最终请求地址就正确了。
最后一步:验证配置
修改完配置后,执行以下命令重新加载Nginx配置:
nginx -s reload
然后访问http://www.example.com/list/findcontent.action?id=6,应该就能正常获取后端内容了。
内容的提问来源于stack exchange,提问作者maston

