Springmvc模式是挂壁OPTIONS请求的,所以需要开启
<servlet> <servlet-name>application</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>dispatchOptionsRequest</param-name> <param-value>true</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet>
1.Controller 添加 @CrossOrigin
Spring MVC 从4.2版本开始增加了对CORS的支持;
2.全局配置
@Configuration public class CorsConfig extends WebMvcConfigurerAdapter { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOrigins("*") .allowedMethods("GET", "HEAD", "POST", "PUT", "PATCH", "DELETE", "OPTIONS", "TRACE"); } }
基于XML的配置
<mvc:cors> <mvc:mapping path="/**" /> </mvc:cors>
这个配置和上面Java方式的第一种作用一样。
同样,你可以做更复杂的配置:
<mvc:cors> <mvc:mapping path="/api/**" allowed-origins="http://domain1.com, http://domain2.com" allowed-methods="GET, PUT" allowed-headers="header1, header2, header3" exposed-headers="header1, header2" allow-credentials="false" max-age="123" /> <mvc:mapping path="/resources/**" allowed-origins="http://domain1.com" /> </mvc:cors>
----------------
实现 WebMvcConfigurer.addCorsMappings
方法
WebMvcConfigurer
是一个接口,它同样来自于 Spring Web
。我们可以通过实现它的 addCorsMappings
方法来针对全局 API 配置 CORS
规则
@Configuration @EnableWebMvc class MvcConfig: WebMvcConfigurer { override fun addCorsMappings(registry: CorsRegistry) { registry.addMapping("/hello") .allowedOrigins("http://localhost:8080") } }
这种方式的缺陷是,filter的顺序是固定的,在引入第三方组件的时候可能会因为filter滞后,导致出错!
2.全局配置CorsFilter
CorsFilter
同样来自于 Spring Web
,但是实现 WebMvcConfigurer.addCorsMappings
方法并不会使用到这个类,具体原因我们后面来分析。我们可以通过注入一个 CorsFilter
来使用它:
@Configuration class CORSConfiguration { @Bean fun corsFilter(): CorsFilter { val configuration = CorsConfiguration() configuration.allowedOrigins = listOf("http://localhost:8080") val source = UrlBasedCorsConfigurationSource() source.registerCorsConfiguration("/hello", configuration) return CorsFilter(source) } }
另一种注入方式,通过注入一个 FilterRegistrationBean
来实现
@Bean public FilterRegistrationBean corsFilter() { UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); CorsConfiguration config = new CorsConfiguration(); config.setAllowCredentials(true); config.addAllowedOrigin("*"); config.addAllowedHeader("*"); config.addAllowedMethod("*"); source.registerCorsConfiguration("/**", config); FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source)); bean.setOrder(0); return bean; }
3.Spring Security
如果您使用的是Spring Security,请确保在Spring Security级别启用CORS,以允许它利用Spring MVC级别定义的配置。
Srping Security Cors 文档
在仅仅引入 Spring Web
的情况下,实现 WebMvcConfigurer.addCorsMappings
方法和注入 CorsFilter
这两种方式可以达到同样的效果,二选一即可。它们的区别会在引入 Spring Security
之后会展现出来,我们后面再来分析。
在引入了 Spring Security
之后,我们会发现前面的方法都不能正确的配置 CORS
,每次 preflight request
都会得到一个 401
的状态码,表示请求没有被授权。这时,我们需要增加一点配置才能让 CORS
正常工作:
@Configuration class SecurityConfig : WebSecurityConfigurerAdapter() { override fun configure(http: HttpSecurity?) { http?.cors() } }
或者,干脆不实现 WebMvcConfigurer.addCorsMappings
方法或者注入 CorsFilter
,而是注入一个 CorsConfigurationSource
,同样能与上面的代码配合,正确的配置 CORS
:
@Bean fun corsConfigurationSource(): CorsConfigurationSource { val configuration = CorsConfiguration() configuration.allowedOrigins = listOf("http://localhost:8080") val source = UrlBasedCorsConfigurationSource() source.registerCorsConfiguration("/hello", configuration) return source }
Reference
Spring 里那么多种 CORS 的配置方式,到底有什么区别
https://blog.csdn.net/ZYC88888/article/details/86534515
没有帐号? 立即注册