为什么Nginx一直重定向我到本地主机?

7
在后端使用Django和Gunicorn,每次我提交表单并应该被发送到example.com/pagetwo时,我却被发送到localhost/pagetwo。由于我对Nginx不熟悉,如果有人能指出问题,我将不胜感激 :)。
default.conf:
server {
    listen       80;
    server_name  example.com;

    location /static/ {
        root /srv;
    }

    location / {
        proxy_redirect off;
        proxy_pass http://unix:/srv/sockets/website.sock;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

这是来自首页的一个表单:

<form id='formone' method='POST' action=''> {% csrf_token %}
    {{ form.as_p }}
    <br />
    <button type="submit" class="btn btn-success btn-sm">Submit</button>
</form>

你的表单操作是否正确? - cdvv7788
我已经从主页面添加了表单标签以供参考。 - derrend
你能通过GET请求访问example.com/pagetwo吗?你修改了你的hosts文件吗? - cdvv7788
你的猜测是正确的,但似乎GwynBleidD比你更快地回答了问题。不过还是非常感谢你的帮助 :) - derrend
2个回答

20
在这种情况下,Django正在监听某些Unix套接字,并且由Nginx发送给Django的所有请求都是本地的,因此Django看到的主机是“localhost”。
当您提交表单时,Django必须构建完整的URL以进行任何重定向。因为Django知道的唯一域名是'localhost',所以Django将使用该主机构建URL。
Nginx用作django和客户端之间的网关,因此它负责更改django发送的所有重定向url以匹配nginx提供站点的域名。但是这行代码:
        proxy_redirect off;

正在告诉nginx“不要这样做,不要重写那些重定向URL”。这会导致重定向问题。

您可以这样做:删除该行或更改nginx配置,以正确通知Django关于域名的信息。为此,您应添加以下行:

        proxy_set_header Host $http_host;

在配置文件中添加这行代码,nginx将会把真实的域名传递给django,而不是传递localhost。这是推荐的方式,因为有了这行代码,nginx对于django来说更加透明。还有其他的头部配置行需要在这里添加,以便django的其他功能可以正常工作。如果想查看所有配置列表,请参考所使用wsgi服务器的文档。对于gunicorn,文档在这里


1
谢谢,这解决了我的问题 :) 我只是想指出,在这种情况下,proxy_redirect off; 这一行是在我第一次搜索问题后添加的,而且即使没有它,问题仍然存在。加入 proxy_set_header Host $http_host; 才是解决之道。再次感谢 :) - derrend
是的,我的错。如果您没有使用Unix套接字,则删除proxy_redirect off;将有所帮助,但在Unix套接字上不会改变任何内容。关于未获取客户端IP地址的问题,您必须在nginx配置中添加:proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - GwynBleidD
再次感谢,我在您提供的答案中找到了nginx文档链接中的IP配置。赞一个,先生 :) - derrend
亲爱的网络匿名者,我向你表示爱意 <3 - Sebas

2

我使用了这个组合,解决了我的问题。

location / {
   proxy_set_header Host $http_host;
   server_name_in_redirect off;
   proxy_redirect off;
   rewrite ^([^.]*[^/])$ https://my-website-url$1/ permanent;   #This will add trailing / to the url which will solve the issue.
}

这对我有用。在我的情况下,我在末尾使用了 proxy_pass http://localhost:port - Bhanu Prakash

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接