前言
跨域是指一个域下的文件想要和另一个域下的资源发生HTTP通信时,浏览器出于安全限制所引发的问题。如果协议、子域名、主域名、端口有任何一个不同,都会出现跨域问题。
举个例子,如果一个网页来自https://www.example.com,那么它只能访问同域下的资源,如https://www.example.com/data.json。但如果它想访问https://api.example.com/data.json或https://www.other.com/data.json,就会因为跨域而被浏览器拦截。
解决
spring 中处理跨域的3种方案
-
在需要配置跨域的接口上 使用 @CrossOrigin注解 当有多个接口时 需要配置多个 过于繁琐 不推荐
java@RestController public class TestController { @GetMapping("/hello") @CrossOrigin(origins = "localhost:8080",allowedHeaders = "*",methods = RequestMethod.GET,allowCredentials = "true",maxAge = 3600L) public String hello() { return "hello"; } }
-
重写 WebMvcConfigurer#taddCorsMappings
java
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedHeaders("*")
.allowedMethods("*")
.allowedOrigins("*")
.allowCredentials(true)
.maxAge(3600);
}
}
- 配置 corsFilter
在如下配置中 我们初始化了CorsConfiguration 并设置了属性 最后将其配置给 UrlBasedCorsConfigurationSource 最后使用 FilterRegistrationBean 注册 corsFilter (使用带UrlBasedCorsConfigurationSource 构造参数进行初始化) 并给corsFilter设置为最高优先级
java
@Configuration
public class CorsConfig {
@Bean
public FilterRegistrationBean<CorsFilter> corsFilter() {
FilterRegistrationBean<CorsFilter> registrationBean = new FilterRegistrationBean<>();
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.setAllowedHeaders(List.of("*"));
corsConfiguration.setAllowedMethods(List.of("*"));
corsConfiguration.setAllowedOrigins(List.of("http://localhost:8081"));
corsConfiguration.setMaxAge(3600L);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", corsConfiguration);
registrationBean.setFilter(new CorsFilter(source));
registrationBean.setOrder(Ordered.HIGHEST_PRECEDENCE);
return registrationBean;
}
}
总结
汇总一下Spring中处理跨域的三种方案的优缺点:
- 使用 @CrossOrigin 注解 灵活 适用于需要跨域的接口不多的情况下。
- 重写 WebMvcConfigurer#taddCorsMappings 统一管理 支持给不同url 配置跨域规则 但是需要引入额外的配置类 本质上使用Interceptor 处理 处理顺序较为靠后
- 配置 corsFilter 统一管理 支持给不同url 配置跨域规则 但是需要引入额外的配置类 ,处理顺序相比较前面两者,并比较靠前。同时会增加接口过滤器的执行链路 (推荐使用)
这就是spring为我们提供的三种跨域方法 ,三种都可以解决问题 任选其中一种即可。需要说明的是:
注意:
@CrossOrigin 注解十 重写 addCorsMappings 方法同时配置,这两种方式中关于跨域的配置会自动合并.跨域在 Cors interceptor 中只处理了一次
@CrossOrigin 注解+ CorsFilter 同时配置,或者重写addCorsMappings 方法 + CorsFitler同时配置,都会导致跨域在 CorsInterceptor 和 CorsFilter 中各处理了一次,降低程序运行效率,这种组合不可取。
good day !!!