我有一台 Apache (2.2) 服务器,其配置如下,用于对在 8080 端口上的 tomcat(6) 上运行的应用程序进行反向代理。
....
ServerName ext-domain
ProxyPreserveHost On
ProxyPass /myapp http://int-domain:8080/myapp
ProxyPassReverse /myapp http://int-domain:8080/myapp
....
当我从浏览器访问以下 URL 时
"http://ext-domain/myapp"
我在浏览器地址栏中得到了以下替换的 URL。
"http://ext-domain:8080/myapp"
并且 Apache 访问日志显示......
"GET /myapp HTTP/1.1" 302 421 "-" "Mozilla/5.0"...
如何避免在响应 URL 中插入此端口 8080?
有人可以帮忙吗?谢谢。
答案1
更新 ProxyPassReverse 如下。
ProxyPassReverse /myapp http://ext-domain/myapp
参考:http://httpd.apache.org/docs/2.2/mod/mod_proxy_ajp.html#usage
答案2
好的,旧答案不完整。罪魁祸首是:ProxyPreserveHost。您几乎不需要此条款。
因此,初始配置模板应该是:
....
ServerName ext-domain
ProxyPass /app http://int-domain:8080/myapp
ProxyPassReverse /app http://int-domain:8080/myapp
....
让你吃惊的 302 响应生成通过后端。您已将标头告知后端Host: ext-domain
,这是的效果ProxyPreserveHost
,因此后端希望表现得友好而听话,并且如果它需要给您 302 重定向,它也会使用ext-domain
与方便给你。Backed 知道你连接的是哪个端口,因此它会尝试使用与方便对你来说。如果它不方便,那么ProxyPreserveHost
首先不要使用它,它是解决问题最干净、最不令人困惑的方法。大多数应用程序(并非全部)不需要ProxyPreserveHost
,而是使用通常的X-Forwaded-xxx
标头。
302处理大致是这样的:
HTTP 302 http://ext-domain:8080/app/foo
由后端生成- Apache 检查配置中是否存在任何
ProxyPassReverse xxx http://ext-domain:8080/app
- 如果匹配,Apache 将继续
HTTP 302 xxx/foo
(在你的情况下,这一步不会发生) - 如果 xxx 不是完整的 URL,则会使用通常的
ServerName
和类似的形式进行扩展(因此 的完整含义ProxyPassReverse /app42 ...
对于 Apache 来说就是302 http://ext-domain/app42
) - Apache 还知道浏览器与 Apache 的 80 端口对话,因此它不会将浏览器误导到 8080,除非您使用错误配置明确告诉它这样做
ServerName
。