笔记簿
ᴄᴏᴅɪɴɢ ɪs ᴀʀᴛ
首页
关于
搜索
登录
注册
SpringMVC处理Https请求重定向后成了Http - 问题解析
#### spring mvc 处理https 请求,redirect后成了http ##### 项目部署背景 目前项目并不是全站的https,而是仅在Nginx上配置了https,其架构大致下面这样 ```text 浏览器 | |(https) Nginx (LoadBalance) 外网 ----------------------------------------- | | | 内网 |(http) |(http) |(http) | | | web web web 应用1 应用2 应用3 ``` - 也就是说https加密,仅限于浏览器到nginx之间,而对web应用来说,所有的请求都是http的,这样如果应用中使用sendRedirect的请求,将会被转发到http。 ```java // 跳转到登录页面 httpServletResponse.sendRedirect(httpServletRequest.getContextPath()+"/login"); return "redirect:/login"; ``` 以上两种写法,当浏览器访问`https://hostname/admin` 时,其实相当于发了两次请求,第二次浏览器会访问到`http://hostname/login`。 解决方案:在响应信息中设置HTTP状态码和location头信息 - 进行URL重定向时,服务器设置HTTP状态码和location头信息,当状态码为302时,表明资源位置临时发生了改变,需要进行重定向,location头信息标识了资源转向的位置,该地址写相对地址。 ```java //跳转到登录页面 httpServletResponse.setStatus(302);//或者303,兼容http1.1 httpServletResponse.setHeader("Location",httpServletRequest.getContextPath()+"/login"); ``` 或者 ```java @Bean @Autowired public InternalResourceViewResolver defaultViewResolver(WebMvcProperties mvcProperties) { InternalResourceViewResolver resolver = new InternalResourceViewResolver(); resolver.setPrefix(mvcProperties.getView().getPrefix()); resolver.setSuffix(mvcProperties.getView().getSuffix()); resolver.setRedirectHttp10Compatible(false); return resolver; } ``` ```java /** * Send a redirect back to the HTTP client. * @param request current HTTP request (allows for reacting to request method) * @param response current HTTP response (for sending response headers) * @param targetUrl the target URL to redirect to * @param http10Compatible whether to stay compatible with HTTP 1.0 clients * @throws IOException if thrown by response methods */ protected void sendRedirect(HttpServletRequest request, HttpServletResponse response, String targetUrl, boolean http10Compatible) throws IOException { String encodedURL = (isRemoteHost(targetUrl) ? targetUrl : response.encodeRedirectURL(targetUrl)); if (http10Compatible) { HttpStatus attributeStatusCode = (HttpStatus) request.getAttribute(View.RESPONSE_STATUS_ATTRIBUTE); if (this.statusCode != null) { response.setStatus(this.statusCode.value()); response.setHeader("Location", encodedURL); } else if (attributeStatusCode != null) { response.setStatus(attributeStatusCode.value()); response.setHeader("Location", encodedURL); } else { // Send status code 302 by default. response.sendRedirect(encodedURL); } } // RedirectHttp10Compatible设置为false else { HttpStatus statusCode = getHttp11StatusCode(request, response, targetUrl); response.setStatus(statusCode.value()); response.setHeader("Location", encodedURL); } } ```