Spring 拦截器postHandle无法修改Response响应头跨域
浏览器控制台信息:
has been blocked by CORS policy: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*'
when the request's credentials mode is 'include'.
The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.
CORS请求默认不发送Cookie和HTTP认证信息。如果要把Cookie发到服务器,一方面要服务器同意,指定Access-Control-Allow-Credentials字段
请求包含credentials(前端设置了withCredentials = true),Access-Control-Allow-Origin 不能使用 * 通配,需要具体指定。
如果controller跳转至页面,postHandle是没问题的。
如果@ResponseBody注释 或者返回 ResponseEntity,在postHandle拦截器中修改请求头,是无效的。
因为方法在先于postHandle方法之前将响应提交给HandlerAdapter(调用handler和Interceptor方法者),所以之后的修改就无效了。
@Override public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object handler, ModelAndView modelAndView) throws Exception { String origin = Optional.ofNullable(httpServletRequest.getHeader("Origin")).orElse(httpServletRequest.getHeader("Referer")); LoggerFactory.getLogger(getClass()).info("origin == null ? * : origin = {}", origin == null ? "*" : origin); httpServletResponse.setHeader("Access-Control-Allow-Origin", origin); httpServletResponse.setHeader("Access-Control-Allow-Credentials ","true"); httpServletResponse.setHeader("Access-Control-Allow-Headers","Origin, X-Requested-With, Content-Type, Accept, Connection, User-Agent, Cookie"); }
可在 `preHandle` 方法中处理。在进入接口方法之前设置跨域响应头。
同时,需要注意有无其他地方更改设置。如 控制器切面(@ControllerAdvice),接口类中的@InitBinder