客户项目需要支持https,我方统一在openshift的router上配置https的域名,然后再反向到POD上,也就是说容器里跑的服务本身还是使用的http,而在一些前后端没有分离的服务内页面上大量使用了html base标签来解决相对路径的问题,而这个base标签里的href的仍然是http的,这会导致在浏览器中报Mixed Content即混合内容错误,当然这个也可以通过设置浏览器的安全策略来解决,但这肯定不是好个办法。于是为了简单直接在页面的head中添加了<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests" />,也确实解决了 这个问题,但是当用户环境只能使用http时,就又会有问题了,因为这个标签会强制把http升级为https。 只好又把upgrade-insecure-requests的标签删除,然后把base标签里的href值通过环境变量的方式注入。
本以为万事大吉,结果还是有部分页面仍然报Mixed Content错误,再次定位发现是代码里有很多地方使用了springMVC的redirect进行跳转,这种方式的跳转在HTTPS的环境下会重定向到HTTP协议,导致无法访问,导致这个问题的根本原因是Spring的ViewResolver对HTTP 1.0协议的兼容。
针对此问题的解决方案是:将redirect
改为RedirectView
类来实现:
modelAndView.setView(new RedirectView("/xxxxxx", true, false));
其中RedirectView
的最后一个参数设置为false,就是将http10Compatible
的开关关闭,不对HTTP 1.0协议进行兼容。
但是项目里使用redirect的地方实在太多,又想看看有没有统一配置的方案,如是又受到了这篇文章的启发:一个HTTPS转HTTP的Bug,他们竟然忍了2年?原谅我无法接受,加班改了! - 掘金
可以配置InternalResourceViewResolver,但最终我的方案是在WebMVCConfig中修改原来spring默认注入的InternalResourceViewResolver这个bean,代码如下:
@Configuration
public class WebMVCConfig implements WebMvcConfigurer {
/**
* 解决 ModelAndView redirect: 后https变成了http的问题
*/
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
InternalResourceViewResolver vr = (InternalResourceViewResolver)ApplicationContextUtil.getContext().getBean("defaultViewResolver");
vr.setRedirectHttp10Compatible(false);
}
}
一切OK!!!