zoukankan      html  css  js  c++  java
  • Springboot配置跨域访问

    CORS 跨域共享

    跨源资源共享(Cross-origin resource sharing, CORS)是由大多数浏览器实现的W3C规范,它允许您以灵活的方式指定哪种跨域请求被授权,而不是使用一些不太安全、功能不太强大的方法,比如IFRAME或JSONP。

    参考之前的文章:通信—跨域资源共享

    Spring BOOT

    从4.2开始,Spring MVC已支持CORS。

    @CrossOrigin

    在Spring Boot中使用带有@CrossOrigin注释的controller方法CORS配置,不需要任何特定的配置。

    @CrossOrigin注解可以在类上使用,也可以在方法上使用,如:

    @CrossOrigin(origins = "http://domain2.com", maxAge = 3600)
    @RestController
    @RequestMapping("/account")
    public class AccountController {
    
        @GetMapping("/{id}")
        public Account retrieve(@PathVariable Long id) {
            // ...
        }
    
        @DeleteMapping("/{id}")
        public void remove(@PathVariable Long id) {
            // ...
        }
    }

    常用的属性有2个,分别是origins和maxAge,下面分别解释下:

    • origins 是一个字符串数组的类型(String []),用于表示那些域名可以访问此接口/映射。多个域名之间用逗号“,”隔开,如果想向所有网址开放,可以直接填写星号“*”。
    • maxAge 还没有找到官方的说明,其他开发者解释为“预请求的结果的有效期”,即COOKIE的有效期,单位是秒。

    如果只在方法上或者类上使用@CrossOrigin注解,则默认该映射接受所有的网站发送过来的请求、接受所有类型的http请求和接受所有的不同内容的头部信息(Header),如:

    @RestController
    @RequestMapping("/account")
    public class AccountController {
    
        @CrossOrigin
        @GetMapping("/{id}")
        public Account retrieve(@PathVariable Long id) {
            // ...
        }
    
        @DeleteMapping("/{id}")
        public void remove(@PathVariable Long id) {
            // ...
        }
    }

    @CrossOrigin可以同时在类上、方法上同时使用,来控制不同网站访问不同的映射,如:

    @CrossOrigin(maxAge = 3600)
    @RestController
    @RequestMapping("/account")
    public class AccountController {
    
        @CrossOrigin("http://domain2.com")
        @GetMapping("/{id}")
        public Account retrieve(@PathVariable Long id) {
            // ...
        }
    
        @DeleteMapping("/{id}")
        public void remove(@PathVariable Long id) {
            // ...
        }
    }

    remove方法可以被所有网站的访问,retrieve方法只接受http://domain2.com网站发送的请求。

    全局CORS配置

    全局CORS配置可以通过注册一个WebMvcConfigurer bean并使用自定义的addcorsmapping (CorsRegistry)方法来定义,如:

    @Configuration
    public class WebMvcConfig extends WebMvcConfigurerAdapter {
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/**")
                    .allowedOrigins("*")
                    .allowedMethods("POST", "GET", "PUT", "OPTIONS", "DELETE")
                    .maxAge(3600)
                    .allowCredentials(true);
        }
    }

    拦截器

    另外,还可以通过添加 Filter 的方式,配置 CORS 规则,并手动指定对哪些接口有效。

    @Bean
    public FilterRegistrationBean corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);    config.addAllowedOrigin("http://localhost:9000");
        config.addAllowedOrigin("null");
        config.addAllowedHeader("*");
        config.addAllowedMethod("*");
        source.registerCorsConfiguration("/**", config); // CORS 配置对所有接口都有效
        FilterRegistrationBean bean = newFilterRegistrationBean(new CorsFilter(source));
        bean.setOrder(0);
        return bean;
    }

    原理剖析

    无论是通过哪种方式配置 CORS,其实都是在构造 CorsConfiguration。 一个 CORS 配置用一个 CorsConfiguration类来表示,它的定义如下:

    public class CorsConfiguration {
        private List<String> allowedOrigins;
        private List<String> allowedMethods;
        private List<String> allowedHeaders;
        private List<String> exposedHeaders;
        private Boolean allowCredentials;
        private Long maxAge;
    }

    Spring 中对 CORS 规则的校验,都是通过委托给 DefaultCorsProcessor实现的。

    DefaultCorsProcessor 处理过程如下:

    1. 判断依据是 Header中是否包含 Origin。如果包含则说明为 CORS请求,转到 2;否则,说明不是 CORS 请求,不作任何处理。
    2. 判断 response 的 Header 是否已经包含 Access-Control-Allow-Origin,如果包含,证明已经被处理过了, 转到 3,否则不再处理。
    3. 判断是否同源,如果是则转交给负责该请求的类处理
    4. 是否配置了 CORS 规则,如果没有配置,且是预检请求,则拒绝该请求,如果没有配置,且不是预检请求,则交给负责该请求的类处理。如果配置了,则对该请求进行校验。

    校验就是根据 CorsConfiguration 这个类的配置进行判断:

    1. 判断 origin 是否合法
    2. 判断 method 是否合法
    3. 判断 header是否合法
    4. 如果全部合法,则在 response header中添加响应的字段,并交给负责该请求的类处理,如果不合法,则拒绝该请求。



    参考:

    SpringBoot CORS 跨域 @CrossOrigin

    SpringBoot配置Cors解决跨域请求问题

  • 相关阅读:
    高进度乘法FFT优化
    Activity的四种加载模式
    异步任务AsyncTask
    利用Handler在子线程中更新UI
    Android 屏幕旋转监听
    HDOJ-1698-线段树成段更新
    HDOJ-1671-字典树
    HDOJ-1251 字典树
    python数据结构与算法
    find the lowest number location
  • 原文地址:https://www.cnblogs.com/Jason-Xiang/p/14505414.html
Copyright © 2011-2022 走看看