Http POST 在 URL 中丢弃端口

Posted

技术标签:

【中文标题】Http POST 在 URL 中丢弃端口【英文标题】:Http POST drops port in URL 【发布时间】:2011-03-24 10:45:36 【问题描述】:

我有一个用 Django 构建的 webapp。我目前正在家里路由器后面的笔记本电脑上运行它。

我已将路由器配置为将发送到特定端口的所有流量路由到该笔记本电脑。

我有 nginx 作为 Apache 的反向代理,使用 mod_wsgi 来运行 Django。

我的问题是:当我尝试提交任何 POST 表单时,端口号会从 url 中删除(例如 209.245.23.201:1552/login/ 变为 209.245.23.201/login/)

这自然会中断。是什么原因造成的(Nginx、Apache、Django?),我该如何解决?

提前致谢。

编辑:表单似乎确实提交了,但我认为重定向失败。

编辑 2:问题肯定出在 Nginx,或者 Nginx 和 Apache 之间的交互。我尝试使用 Apache 作为唯一服务器的设置,运行 django,它运行良好。所以要么 Nginx 放弃​​了端口,要么 Apache 被 Nginx 作为代理弄糊涂了。随便

【问题讨论】:

愚蠢的问题......你怎么知道端口号被丢弃了?你是怎么知道的? 它确实会从我地址栏中的网址中删除。 这可能是浏览器问题。你用的是什么浏览器? 听起来好像重定向有问题。我们必须查看实际导致重定向的代码,以便可能告诉您它为什么这样做。 不是浏览器。我尝试了 Chromium 和 Firefox。登录后 Django 正在执行重定向,但这只是返回 HttpResponseRedirect('/dashboard/')。当我运行 Django 测试服务器时这不是问题,只有当我通过 Nginx 和 Apache 连接时才会发生。 【参考方案1】:

鉴于您所关心的一切都是明确的 HTTP(例如与 AJP 不同),我会在主机上运行诸如 Wireshark 之类的协议分析器并确定引入重定向的位置。

【讨论】:

【参考方案2】:

检查错误日志。在 Linux 上,我的位于 /var/log/apache2。只需搜索 error.log 即可。

【讨论】:

【参考方案3】:

我的开发服务器也有同样的问题。 经过一番互联网搜索,我发现了这个讨论(nginx, apache, and odd admin error),解决方案是修改 nginx 的代理配置。

要修改的配置设置是:

proxy_set_header            Host $host;

解决方法是添加端口号:

proxy_set_header            Host $host:$server_port;

在我的 ngnix + apache2 (with worker mpm) + django 现在一切正常。

【讨论】:

我的家庭开发环境遇到了完全相同的问题,这解决了它。这应该是这个问题的公认答案。 在我的情况下 $server_port 没有被解析,我不得不手动放置我的 server_port ("$host:8080")。 感谢 Techside,这太棒了。我要补充一点,在 Vagrant 中运行 Nginx+Django 时,我必须和 Amit 做同样的事情,其中​​ Vagrant 将 external:8000 映射到 internal:80,而 nginx 在 internal:8000 处将 internal:80 代理到 django。 $server_port 未解析,可能是由于在 nginx 上为 80。 我在 NGINX 和 gunicorn 上遇到了同样的问题,上面的答案修复了它。谢谢! FWIW,您可能还需要从浏览器中清除缓存的重定向。【参考方案4】:

您想传递到达 nginx 的原始 HTTP Host 标头:

proxy_set_header Host $http_host;

这似乎是 Debian/Ubuntu 中 nginx 的默认配置的错误,它仅使用 $host$host 将不包含 $server_port。 (这是在 /etc/nginx/proxy_params 中为 Debian/Ubuntu 软件包配置的,您可以在包含它后在配置中覆盖它。)

请注意$host:$server_port$http_host 不同。 请参阅http://wiki.nginx.org/HttpCoreModule#.24host 了解说明。

在 Debian 中报告并修复:http://bugs.debian.org/733016

【讨论】:

这解决了我的问题。接受的答案不 这绝对是要走的路。我正在通过 Vagrant 实例进行隧道传输,因此我的端口在 nginx 服务器、Django 服务器和浏览器端是不同的。 请原谅这个菜鸟问题,但是 nginx 配置中的 proxy_set_header 行在哪里?在位置块内?在听线之后?别的地方?谢谢! 我得到了“proxy_set_header Host $http_host;”解决我的nginx、gunicorn、django 使用 $http_host 解决了我的问题。我在debian下运行nginx(官方docker镜像)【参考方案5】:

如果您发现从模型的 get_absolute_url() 方法派生的 url 发生这种情况,您应该使用将该路径传递给 HttpRequest.build_absolute_url() 以便将主机名和端口添加到路径中。

【讨论】:

以上是关于Http POST 在 URL 中丢弃端口的主要内容,如果未能解决你的问题,请参考以下文章

牛仔在端口 80 上丢弃一些数据包

tinyhttpd ------ C 语言实现最简单的 HTTP 服务器

Ajax相关——get请求和post请求的区别

Python 将 http post body 扭曲转发到 tcp 端口

API开发实践 接受url请求

Request.Url 有错误的端口信息