Spring Boot Cors

问题的起因

今天公司的一个小项目需要跑到Android上面,本身是通过token鉴权的,所以移植比较简单。但是在处理 跨域 问题的时候着实给踩了个大坑。
网上说的重写 addCorsMapping等方法在一般处理上没有大问题. 但是在统一异常拦截器上面有很大的问题.
spring提供的跨域, 只是在响应是Controller时生效, 而统一异常拦截器ControllerAdvice是通过AOP处理的. 并且我们在很多时候需要通过自己的拦截器, 过滤器处理内容. 所以spring提供的跨域封装, 并不能很好的解决问题. 最后通过自己编写Filter解决了这个问题. 在此做一个小记录, 以后遇到需要跨域的问题时,直接使用此方法, 比使用spring封装的内容要好很多.

顺便提一下, 关于跨域时 PUTDELETE两个复杂请求的参数处理, 由于这两个请求在发起之前都会发起一个 预请求, 具体可以看一下 这篇博客, 如果不做处理的话, PUT请求将得不到参数. 具体处理方法也在下面代码区给出.

更新:
是我太年轻, 统一异常拦截器还是没有办法正常的返回, 最后在统一异常拦截器的response上面加上了Origin的设置. 下面展示代码

@CrossOrigin
response.setHeader("Access-Control-Allow-Origin", "*");

代码

@WebFilter
public class CorsFilter extends OncePerRequestFilter {
    private static final String ORIGIN = "Origin";
    private static final String HEADERS = "Access-Control-Request-Headers";

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        // 获取请求头中的 'Origin' 信息
        String origin = request.getHeader(ORIGIN);
        // 获取请求头中的 'header' 信息
        String headers = request.getHeader(HEADERS);

        /**
         * 1.支持任何域名跨域访问
         * 当 'Access-Control-Allow-Origin' 设置为 '*' 时,不能解决带 Cookie 的跨域
         */
        if (!StringUtils.isEmpty(origin)) {
            response.setHeader("Access-Control-Allow-Origin", origin);
        }

        /**
         * 2.支持自定义请求头的跨域
         */
        if (!StringUtils.isEmpty(headers)) {
            response.setHeader("Access-Control-Allow-Headers", headers);
        }

        // 3.设置支持带 Cookie 的跨域请求
        response.setHeader("Access-Control-Allow-Credentials", "true");
        // 4.设置允许跨域请求的方法形式 'GET'、'DELETE' 等
        response.setHeader("Access-Control-Allow-Methods", "*");
        // 5.设置非简单请求的预检命令缓存时间,单位 's'
        response.setHeader("Access-Control-Max-Age", "1728000");

        if ("OPTIONS".equals(request.getMethod())) {
            response.setStatus(HttpServletResponse.SC_OK);
        } else {
            filterChain.doFilter(request, response);
        }

    }
}



针对PUT请求参数的处理
@Component
public class PutFilter extends HttpPutFormContentFilter {

}