跨域后端处理
无    2020-03-25 09:52:09    350    0    0
xianglijiaxing


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


上一篇: H5 分享

下一篇: class 样式动态绑定

350 人读过
立即登录, 发表评论.
没有帐号? 立即注册
0 条评论
文档导航