springboot设置跨域的几种方式

单个Controller及方法:

@CrossOrigin作为一个强大的注解,特点就是不仅支持在controller中设置,还支持方法级注解。而最简单也最直接的方法,那就是在controller中直接加入。

@CrossOrigin(origins = "*",allowCredentials = "true")

全局跨域:

上述方法@CrossOrigin虽然支持单位注解,但是若是要配置全局,未免就太过繁琐了。这时候可以尝试以下三种方法。

1. servlet过滤器Filter

通过自定义自己的OriginFilter,实现javax.servlet.Filter接口里的doFilter方法,并声明为Component组件,贴出关键代码如下:

@Override
    public void doFilter(ServletRequest req, ServletResponse res,
                         FilterChain chain) throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) res;
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE,PUT");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers",
                "Origin, X-Requested-With, Content-Type, Accept, " + "X-CSRF-TOKEN");
        response.setHeader("Access-Control-Allow-Credentials","true");
        chain.doFilter(req, res);
    }

2. 设置CorsConfiguration

使用spring自带的CorsConfiguration解决跨域问题,并使用@Configuration声明为配置类。代码如下:

@Configuration
public class CustomCORSConfiguration {
    private CorsConfiguration buildConfig() {
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.addAllowedOrigin("*");
        corsConfiguration.addAllowedHeader("*");
        corsConfiguration.addAllowedMethod("*");
        corsConfiguration.setAllowCredentials(true);
        return corsConfiguration;
    }

    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", buildConfig());
        return new CorsFilter(source);
    }

}

3. WebMvcConfigurer

在spring2.0中,通过自定义的WebMvcConfigurer可以让我们进一步地自定义自己的web项目,同样的,我们可以在这处理相关的跨域问题。首先,我们需要创建一个配置类,让它继承自WebMvcConfigurationSupport,同时使用@Configuration注解标记该配置类。然后重写它的addCorsMappings即可。代码如下:

@Configuration
public class WebMvcConfigurer extends WebMvcConfigurationSupport{

   @Override
    protected void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**").allowedOrigins("*")
                .allowCredentials(true).allowedMethods("*").maxAge(3600);
    }
}

此外,还可以在该配置类通过重写addViewControllers方法配置项目启动的首页,以及通过addResourceHandlers方法控制静态资源的请求路径,包括下述的拦截器也可以通过重写这里的addInterceptors方法进行添加。

4. 自定义拦截器重写请求

此外,我们还可以自定义一个拦截器,通过在preHandle中拦截到的HttpServletResponse,对header重新进行设置。对header的设置同方法1,然后再方法3中的WebMvcConfigurer中,通过重写addInterceptors方法添加该拦截器即可。有兴趣的读者可以自行实现。

重点:

无论采用上述哪种方式,在进行跨域访问的时候,必须设置withCredentials为true,以jquery为例,ajax请求中须添加

  xhrFields: {  withCredentials: true },

总结:

上述解决方式几乎都是通过重新设置HttpServletResponse的header实现的。其中,关键代码为:

response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Credentials","true");
经验分享 程序员 微信小程序 职场和发展