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

原文地址:https://www.cnblogs.com/foolash/p/14011694.html