解决nginx 反代 tomcat 应用不能获取到正确域名
时间:2019-11-28 16:14 作者:admin 分类: 技术文章
今天在帮朋友迁移部署tomcat应用得时候遇到了这么个问题:原来是在Windows服务器上直接使用tomcat部署到80端口的,新机器是Linux+宝塔面板,要是直接部署到80端口,其他网站或者nginx这类的就只能换端口,很是不方便,我就建议她使用nginx反代tomcat应用,那么问题就来了,我不是第一次使用nginx反代,但是之前都是反代后端的网络应用,不存在这些问题,使用宝塔添加了网站后,把应用上传到tomcat的webapps目录下,名称为shop,在网站设置启用tomcat,但是测试的时候就发现后端不能获得网站使用者正确的请求域名,获取的是本地的,http://127.0.0.1:8080/shop/xxxxxx,导致出现一些bug,返回的路径是本地的:
经过初略阅读+搜索应用源代码,找到了关键代码:
想吐槽一下这个程序员,不合格!!!这都9102年了,判断居然没有443???WTF!!!不让程序使用SSL???什么操作。。。
先说一下这个 request.getServerName() ,根据API上写的:
Reconstructs the URL the client used to make the request. The returned URL contains a protocol, server name, port number, and server path, but it does not include query string parameters.
也就是说, getRequestURL() 输出的是不带query string的路经(含协议 端口 server path等信息).
并且,还发现:
request.getScheme() //总是 http,而不是实际的http或https request.isSecure() //总是false(因为总是http) request.getRemoteAddr() //总是 nginx 请求的 IP,而不是用户的IP request.getRequestURL() //总是 nginx 请求的URL 而不是用户实际请求的 URL response.sendRedirect( 相对url ) //总是重定向到 http 上 (因为认为当前是 http 请求)
接下来就该批斗宝塔了!
看看默认的启用tomcat的配置里面没有 proxy_set_header Host $host;
最关键的就是没有这个,导致后端的Java程序的 request.getServerName() 获取不到正确的域名!
所以解决办法也简单,那就是在你的反代location里面加上 proxy_set_header Host $host; 后端就可以正确获取到当前的浏览器域名了。完事儿。
最后说一下,如果后端不是我上面说的那个不合格的程序员写的没有判断HTTPS的话,只需要在location里面添加 proxy_set_header X-Forwarded-Proto $scheme; 即可正确处理HTTPS了。
日常踩坑记录。。。
参考:
https://www.cnblogs.com/interdrp/p/4881785.html
https://blog.csdn.net/tpkey/article/details/18550039