使用Nginx代理uWSGI/Django时,如何移除请求的父路径?
解决Nginx反向代理时去除路径前缀的问题
你遇到的核心问题是Nginx当前只是直接转发请求,没有修改路径前缀,导致Django收到的请求仍带着/secure/rest/前缀,但你的Django路由并没有配置这个前缀,所以才会返回404错误。
下面给你两种简单可行的解决方案,任选其一即可:
方法一:用rewrite指令重写路径
修改你的Nginxlocation配置块,添加路径重写规则:
location /secure/rest/ { # 正则匹配并去除/secure/rest/前缀,保留后续路径和参数 rewrite ^/secure/rest/(.*)$ /$1 break; uwsgi_pass django; include /etc/nginx/uwsgi_params; }
rewrite ^/secure/rest/(.*)$ /$1 break;:这条规则会把/secure/rest/后面的所有内容提取出来,重写为以/开头的路径(比如原请求/secure/rest/rabbits/list?foo=baloo会被处理成/rabbits/list?foo=baloo),break表示停止后续的rewrite规则处理。- 修改完成后重启Nginx:
sudo systemctl restart nginx,再测试请求就能看到Django收到的路径已经去掉了前缀。
方法二:直接修改uWSGI请求参数
如果你不想用rewrite,也可以通过覆盖REQUEST_URI参数来传递处理后的路径:
location /secure/rest/ { uwsgi_pass django; include /etc/nginx/uwsgi_params; # 处理路径,去掉/secure/rest/前缀 set $new_path $uri; if ($new_path ~ ^/secure/rest/(.*)) { set $new_path /$1; } # 拼接路径和参数,传递给Django uwsgi_param REQUEST_URI $new_path$is_args$args; }
这种方式通过Nginx变量处理生成去掉前缀的路径,再传递给uWSGI,同样能实现需求。
验证修改效果
重启Nginx后再次发送请求http://www.example.com/secure/rest/rabbits/list?foo=baloo,查看Django日志,应该会看到请求路径变成了/rabbits/list?foo=baloo,这样就能匹配到你Django中对应的路由了。
内容的提问来源于stack exchange,提问作者Duke Dougal
相关产品推荐
相关产品推荐

