Tomcat 8能否跨域名重写URL且不跳转保留原浏览器地址?
问题现状
- 运行环境:Tomcat 8旧版本,短期内无法替换为其他服务程序,操作人仅1天Tomcat使用经验,查阅官方文档、公开技术资料暂未找到可行解决方案
- 域名资源:持有
domaina.com、domainb.com两个域名 - 核心需求:用户访问
https://domaina.com/v时,服务实际返回https://domainb.com的内容,浏览器地址栏始终保留原始URLhttps://domaina.com/v不变 - 已完成配置:已在Tomcat中启用重定向Valve,在
WEB-INF目录下创建rewrite.config配置文件,可确认配置修改可被Tomcat正常读取 - 当前生效的rewrite规则:
RewriteRule ^/v$ https://domainb.com [R]
- 已尝试方案及问题:
- 配置
[R]标记:触发302跳转,浏览器地址栏直接变更为https://domainb.com,不符合地址栏保留原始URL的要求 - 将
[R]替换为[P]代理标记:访问直接返回404错误 - 查阅技术博客得知Tomcat原生不支持该类跨域隐式重写,需要安装Apache作为反向代理才能实现效果,希望在尝试该方案前找到更轻量的实现路径
- 配置
可行方案(无需额外安装Apache/Nginx)
用[P]标记返回404的核心原因是:Tomcat重写Valve的[P]标记和Apache Httpd的实现逻辑完全不同,它默认不会自动发起跨域代理请求,只会尝试匹配本地应用内的路径资源,找不到对应内容自然返回404。Tomcat 8本身自带代理Servlet,直接配置即可实现地址栏不变的跨域内容返回,步骤如下:
- 配置Tomcat内置代理Servlet
打开应用的WEB-INF/web.xml文件,新增如下配置:
如果domainb.com下还有子路径资源需要代理(比如静态js、css文件),就把<servlet> <servlet-name>crossProxy</servlet-name> <servlet-class>org.apache.catalina.servlets.ProxyServlet</servlet-class> <init-param> <param-name>targetUri</param-name> <param-value>https://domainb.com</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>crossProxy</servlet-name> <url-pattern>/v</url-pattern> </servlet-mapping>url-pattern改成/v/*,targetUri改成https://domainb.com/即可 - 调整rewrite规则
把原有rewrite.config里的规则替换为以下内容,把匹配到的/v路径请求转发给上面配置的代理Servlet处理:RewriteRule ^/v(/.*)?$ /v$1 [L] - 重启对应Tomcat应用,清空浏览器缓存后测试即可。此时所有访问
https://domaina.com/v的请求会由Tomcat内部拉取domainb.com的响应内容返回给客户端,浏览器全程不会收到跳转指令,地址栏会一直保留原始URL。
注意:如果目标站点
domainb.com的页面内写死了带域名的绝对路径资源引用,需要额外做内容替换处理,否则会出现资源加载失败的问题,常规业务场景下上述配置已经可以满足需求。
内容的提问来源于stack exchange,提问作者stuartah
相关产品推荐
相关产品推荐

