Spring配置跨域

Spring进行跨域配置,通过CrossOrigin注解,addCorsMappings方法以及添加CorsFilter过滤器的三种方式实现。

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    /**
     * 注解方式进行跨域设置,可以加在方法或类上,如果加在controller上,那么就表明该controller下的所有接口都支持跨域
     * CrossOrigin注解是在AbstractHandlerMethodMapping的内部类mappingRegistry的register方法中完成解析
     * 根据注解中的属性来创建一个corsConfiguration对象,将CrossOrigin标注的请求方法的HandlerMethod与创建的corsConfiguration
     * 一一对应,加入到corsLookup的Map映射中
     * 当请求到达DispatcherServlet#doDispatch之后,调用AbstractHandlerMapping#getHandler获取执行链
     * HandlerExecutionChain时,会从corsLookup中获取到对应的corsConfiguration对象
     * 将corsConfiguration构建成一个corsInterceptor拦截器,然后由拦截器调用DefaultCorsProcessor#processRequest,来进行跨域请求的校验工作
     */
    @CrossOrigin(
            allowedHeaders = "*",
            methods = {RequestMethod.POST},
            originPatterns = "*",
            maxAge = 3600,
            allowCredentials = "true"
    )
    @PostMapping("/**")
    public void cors() {

    }


    /**
     * 通过FilterRegistrationBean来配置一个过滤器,处理跨域请求。
     * 这个方式既可以处理跨域,也可以处理其他请求
     * 本质是调用CorsFilter的doFilterInternal方法,触发对DefaultCorsProcessor#processRequest的调用
     * 从而完成对跨域请求的处理。与@CrossOrigin与addCorsMappings方法的区别在于执行时机的不同
     * CorsFilter的执行顺序在所有过滤器之前,而@CrossOrigin与addCorsMappings方法在所有过滤器之后。
     *
     * @return FilterRegistrationBean
     */
    @Bean
    public FilterRegistrationBean<CorsFilter> corsFilter() {
        FilterRegistrationBean<CorsFilter> corsFilter = new FilterRegistrationBean<>();
        //创建CorsConfiguration对象 与addCorsMappings和@corsOrigin相同 都离不开CorsConfiguration
        //区别在于以上两者是自动创建 而这里需要手动创建
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(List.of("*"));
        configuration.setAllowedMethods(List.of("*"));
        configuration.setAllowedHeaders(List.of("*"));
        configuration.setAllowedOriginPatterns(List.of("*"));
        configuration.setMaxAge(3600L);
        configuration.setAllowCredentials(true);
        //创建UrlBasedCorsConfigurationSource对象 用于将CorsConfiguration对象与URL进行匹配
        //并将这个映射匹配关系保存到UrlBasedCorsConfigurationSource的corsConfigurations集合中
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        //创建CorsFilter对象 并将UrlBasedCorsConfigurationSource对象作为参数传入
        corsFilter.setFilter(new CorsFilter(source));
        corsFilter.setOrder(-1); //设置过滤器优先级 值越小优先级越高
        return corsFilter;
    }

    /**
     * 配置全局跨域,通过重写WebMvcConfigurer的addCorsMappings方法实现
     * 这种配置与@CrossOrigin注解相同,最终都是在corsInterceptor中发起对触发对DefaultCorsProcessor#processRequest的调用
     * 执行要晚于CorsFilter
     * registry的addMapping方法配置了一个CorsRegistration对象,该对象中包含了一个CorsConfiguration参数,用于保存addMapping的配置
     * 在WebMvcConfigurationSupport#requestMappingHandlerMapping方法中触发addCorsMappings方法,将该方法创建的对象组装为一个
     * UrlBasedCorsConfigurationSource对象,该对象中含有一个Map<String, CorsConfiguration> corsConfigurations,用于保存addMapping的配置
     * 将这个UrlBasedCorsConfigurationSource对象赋值给AbstractHandlerMapping#corsConfigurationSource
     * 当请求到达时,会在AbstractHandlerMapping#getHandler中进行处理,与@corsOrigin注解不同的是,这里获取CorsConfiguration是从
     * corsConfigurationSource,而注解是从corsLookup集合中获取,
     * 最后将获取到的CorsConfiguration对象组装为corsInterceptor拦截器后,调用方法进行跨域校验
     *
     * @param registry CorsRegistry
     */
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedMethods("*")
                .allowedHeaders("*")
                .allowedOrigins("*")
                .allowedOriginPatterns("*")
                .maxAge(3600)
                .allowCredentials(true);
    }
}
  • 7
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

crack_comet

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值