• spring boot / cloud (六) 开启CORS跨域访问 obejct


    spring boot / cloud (六) 开启CORS跨域访问

    前言

    什么是CORS?

    Cross-origin resource sharing(跨域资源共享),是一个W3C标准,它允许你向一个不同源的服务器发出XMLHttpRequest请求,从而克服了ajax只能请求同源服务的限制.并且也可以通过灵活的设置,来指定什么样的请求是可以被授权的.

    什么是跨域?

    假设你在http://xxx.com/test/下有一个js文件,从这个js里发出一个ajax请求请求后端服务,按照如下情况判定:

    请求地址 原因 结果
    http://xxx.com/xxxx/action 同一域名,不同文件夹 非跨域
    http://xxx.com/test/action 同一域名,同一文件夹 非跨域
    http://a.xxx.com/test/action 不同域名,文件路径相同 跨域
    http://xxx.com:8080/test/action 同一域名,不同端口 跨域
    https://xxx.com/test/action 同一域名,不同协议 跨域

    还有那些其他的跨域解决方案?

    • JSONP : 动态添加一个<script>标签,而script标签的src属性是没有跨域的限制的。这样说来,这种跨域方式其实与ajax XmlHttpRequest协议无关了,而缺点也很明显,它只支持GET请求而不支持POST等其它类型的HTTP请求;它只支持跨域HTTP请求这种情况,不能解决不同域的两个页面之间如何进行JavaScript调用的问题

    • NGINX代理 : 通过一个代理服务器,将跨域的请求转发,如:前端JS在http://www.demo.com/a.js,后端是http://www.abc.com/app/action,通过代理可将后端的地址转换成http://www.demo/app/action,这样,从前端发起的请求,就不存在跨域的情况了

    然后CORS是支持所有类型的HTTP请求,并且也只是服务端进行设置即可,但是缺点就是老的浏览器不支持CORS(如:IE7,7,8,等)

    思路

    CORS的响应头

    • Access-Control-Allow-Origin : 必须的,允许的域名,如果设置*,则表示接受任何域名

    • Access-Control-Allow-Credentials : 非必须的,表示是否允许发送Cookie,注意,当设置为true的时候,客户端的ajax请求,也需要将withCredentials属性设置为true

    • Access-Control-Expose-Headers : 非必须的,表示客户端能拿到的header,默认情况下XMLHttpRequestgetResponseHeader方法只能拿到几个基本的header,如果有自定义的header要获取的话,则需要设置此值

    • Access-Control-Request-Method : 必须的,表示CORS上会使用到那些HTTP方法

    • Access-Control-Request-Headers : 必须的,表示CORS上会有那些额外的的有信息

    CORS将请求分为两种类型

    两种类型分别为简单请求非简单请求,同时满足以下两大条件的请求被定义为是简单请求:

    • 请求方法是以下三种之一:

    • HEAD

    • GET

    • POST

    • HTTP头信息不超出以下几种字段:

    • Accept

    • Accept-Language

    • Content-Language

    • Last-Event-ID

    • Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain

    对于非简单请求,浏览器会自动发一个预检请求,这个请求是OPTIONS方法的,主要是询问服务器当前请求是否在允许范围内

    实现

    1.方式A:使用@CrossOrigin来标记指定的方法(小范围跨域)

    @RequestMapping(value = "add", method = RequestMethod.GET)
    @CrossOrigin(methods = { RequestMethod.GET, RequestMethod.POST }, origins = "*")
    public RestResponse<Integer> add(Integer a, Integer b) {
        return new RestResponse<>(demoService.add(a, b));
    }
    

    2.方式B:使用spring boot的默认配置来设定全局跨域

    endpoints.cors.allow-credentials=
    endpoints.cors.allowed-headers=
    endpoints.cors.allowed-methods=GET
    endpoints.cors.allowed-origins=
    endpoints.cors.exposed-headers=
    endpoints.cors.max-age=1800
    

    3.方式C:使用WebMvcConfigurer自定义配置跨域

    定义CorsRegistrationConfig类

    public static class CorsRegistrationConfig {
        //描述 : 扫描地址
        private String mapping = "/**";
        //描述 : 允许证书
        private Boolean allowCredentials = null;
        //描述 : 允许的域
        private String allowedOrigins = "*";
        //描述 : 允许的方法
        private String allowedMethods = "POST,GET,DELETE,PUT";
        //描述 : 允许的头信息
        private String allowedHeaders = "*";
        
        .........省略
    }
    

    定义CorsConfig类

    @Configuration
    @ConfigurationProperties(prefix = "org.itkk.cors")
    @Validated
    public class CorsConfig {
    
      //描述 : 跨域信息
      @NotNull
      private Map<String, CorsRegistrationConfig> config;
      
      .....省略
    
    }
    

    定义重写addCorsMappings方法

      @Bean
      public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurerAdapter() {
          @Override
          public void addCorsMappings(CorsRegistry registry) {
            //扫描地址
            if (!CollectionUtils.isEmpty(config)) {
              Iterator<String> keys = config.keySet().iterator();
              while (keys.hasNext()) {
                String key = keys.next();
                CorsRegistrationConfig item = config.get(key);
                CorsRegistration cr = registry.addMapping(item.getMapping());
                if (item.getAllowCredentials() != null) {
                  cr.allowCredentials(item.getAllowCredentials());
                }
                if (StringUtils.isNotBlank(item.getAllowedOrigins())) {
                  String[] allowedOriginArray = item.getAllowedOrigins().split(",");
                  cr.allowedOrigins(allowedOriginArray);
                }
                if (StringUtils.isNotBlank(item.getAllowedMethods())) {
                  String[] allowedMethodArray = item.getAllowedMethods().split(",");
                  cr.allowedMethods(allowedMethodArray);
                }
                if (StringUtils.isNotBlank(item.getAllowedHeaders())) {
                  String[] allowedHeaderArray = item.getAllowedHeaders().split(",");
                  cr.allowedHeaders(allowedHeaderArray);
                }
              }
            }
          }
        };
      }
    

    配置文件,可根据不同的mapping设置不同的cors规则

    org.itkk.cors.config.demo.mapping=/**
    org.itkk.cors.config.demo.allowCredentials=
    org.itkk.cors.config.demo.allowedOrigins=
    org.itkk.cors.config.demo.allowedMethods=
    org.itkk.cors.config.demo.allowedHeaders=
    

    使用jquery,在跨域场景下进行测试

        $(function(){
    		$.ajax({
                url:'http://127.0.0.1:8080/demo/c',
                headers:{
                    'aheader':'111'
                },
                type:'GET',
                dataType:'json',
                success:function(data){
                    console.log(1);
                    console.log(data);
                    console.log(2);
    
                }
            });
        });
    

    代码仓库 (博客配套代码)

    结束

    演示了单spring boot的应用的,在后续的章节中,会找机会写一下在微服务场景下(spring cloud)的跨域设置


    想获得最快更新,请关注公众号

    想获得最快更新,请关注公众号

  • 相关阅读:
    Vue实例的生命周期created和mounted的区别
    Vue实例的生命周期created和mounted的区别
    20172326『Java程序设计』课程结对编程练习_四则运算第二周阶段总结
    Coverage数据拓扑
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
  • 原文地址:https://www.cnblogs.com/itkk/p/7447118.html
Copyright © 2020-2023  润新知