跨域解决之CorsFilter与WebMvcConfigurer篇

跨域解决之CorsFilter与WebMvcConfigurer篇

平时在做前后端分离的项目开发的时候经常会遇到跨域问题,这里对解决方案做一个总结

先说一下跨域产生的原因:

跨域的原因其实很简单,就是浏览器的同源策略。同源策略是一种约定,同源策略会阻止一个域的javascript脚本和另外一个域的内容进行交互。只要两个站点的域名或ip、端口、协议中的任意一个不同就认为是跨域。同源策略是为了保证web应用的安全性,但是会给开发造成麻烦。

解决方案

WebMvcConfigurer

这是spring官方给出的解决跨域的方法,
spring CorsSupport

@Configuration(proxyBeanMethods = false)
public class MyCorsConfiguration {

    @Bean
    public WebMvcConfigurer corsConfigurer() {
    return new WebMvcConfigurer() {
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/**")
                    .allowCredentials(true)
                    .allowedHeaders("*")
                    .allowedOrigins("")
                    .allowedMethods("*")
                    .allowCredentials(true)
                    .maxAge(3600);
        }
    };
  }
}

这个方法十分的简单,但是在实际场景中使用起来可能会遇到一些麻烦,比如我们现在需要对请求路径进行拦截,要实现这个需求就要添加拦截器,现在我们在上面的代码上添加拦截器的代码

@Configuration(proxyBeanMethods = false)
public class MyCorsConfiguration {

    @Bean
    public WebMvcConfigurer corsConfigurer() {
    return new WebMvcConfigurer() {
    	// 跨域配置
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/**")
                    .allowCredentials(true)
                    .allowedHeaders(allowedHeader)
                    .allowedOrigins(allowedOrigins)
                    .allowedMethods("*")
                    .allowCredentials(true)
                    .maxAge(3600);
        }

		@Override
    	public void addInterceptors(InterceptorRegistry registry) {
        // 注册的路由拦截器
        registry.addInterceptor(new SaRouteInterceptor())
                .addPathPatterns("/admin/**")
                .excludePathPatterns("/admin/login");
    	}
    };
  }
}

上面这段代码看似很完美,其实是有问题的
使用上面这段代码时你会发现,被拦截的路径出现了跨域问题,而未被拦截的路径则可以正常请求,出现这种情况的原因则是由于请求在知道本次请求可以跨域之前就已经被拦下来了,自然就认为该站点不能允许跨域,就出现了跨域的情况。

CorsFilter

为了解决上面的情况,我们就要说到另一种解决跨域的方式了,即CorsFilter.
先上代码


@Configuration
public class CorsConfig {

    @Value("${cors.allowedHeader}")
    String allowedHeader;
    @Value("${cors.allowedOrigins}")
    String allowedOrigins;

//配置跨域
    @Bean
    public CorsFilter corsFilter() {
        CorsConfiguration config = new CorsConfiguration();
        // 设置允许跨域请求的域名
        config.addAllowedOrigin(allowedOrigins);
        // 是否允许证书
         config.setAllowCredentials(true);
        // 设置允许的方法
        config.addAllowedMethod("*");
        // 允许任何头
        config.addAllowedHeader(allowedHeader);
        UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource();
        configSource.registerCorsConfiguration("/**", config);
        return new CorsFilter(configSource);
    }

// 注册的路由拦截器
    @Bean
    public WebMvcConfigurer corsConfigurer() {
    return new WebMvcConfigurer() {
		@Override
    	public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new SaRouteInterceptor())
                .addPathPatterns("/admin/**")
                .excludePathPatterns("/admin/login");
    	}
    };
  }
}

通过这两个bean,就可以实现跨域配置的同时进行路由拦截的需求。至于为什么CrosFilter可以做到Interceptor做不到的事情,是因为前者是过滤器后者是拦截器,过滤器是servlet提供的,而拦截器是spring提供的,过滤器的执行时机要早拦截器的,所以就可以在请求被拦截前允许跨域
在这里插入图片描述

  • 9
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
在SpringBoot中,解决问题有多种方式,下面介绍三种常用方法: 1. 使用注解@CrossOrigin 在Controller类或方法上加上@CrossOrigin注解即可解决问题,示例代码如下: ```java @RestController @CrossOrigin(origins = "*", maxAge = 3600) public class MyController { @RequestMapping("/hello") public String hello() { return "Hello World!"; } } ``` 这里的@CrossOrigin注解中的origins参数表示允许来自哪些名的请求,*表示允许所有名的请求;maxAge参数表示缓存时间,单位为秒。 2. 添加Filter 通过添加Filter来解决问题,示例代码如下: ```java @Component public class CorsFilter implements Filter { @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"); response.setHeader("Access-Control-Max-Age", "3600"); response.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization, X-Requested-With"); chain.doFilter(req, res); } } ``` 这里的CorsFilter类需要添加@Component注解,然后在doFilter方法中设置Access-Control-Allow-Origin等相关Header。 3. 使用WebMvcConfigurer 使用WebMvcConfigurer来配置问题,示例代码如下: ```java @Configuration public class CorsConfiguration implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOrigins("*") .allowedMethods("GET", "POST", "PUT", "DELETE") .maxAge(3600); } } ``` 这里的CorsConfiguration类需要添加@Configuration注解,并实现WebMvcConfigurer接口,然后在addCorsMappings方法中配置相关参数。
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值