zoukankan      html  css  js  c++  java
  • SpringBoot入门教程(十三)CORS方式实现跨域

    什么是跨域?浏览器从一个域名的网页去请求另一个域名的资源时,域名、端口、协议任一不同,都是跨域 。 跨域资源访问是经常会遇到的场景,当一个资源从与该资源本身所在的服务器不同的域或端口请求一个资源时,资源便会发起一个跨域 HTTP 请求。出于安全考虑,浏览器会限制从脚本内发起的跨域HTTP请求。

    vCORS方式实现跨域

    跨域的方式有很多种, 今天主要介绍CORS(网络通信技术),全称Cross-Origin Resource Sharing  ,是一种允许当前域(domain)的资源(比如html/js/web service)被其他域(domain)的脚本请求访问的机制,通常由于同域安全策略(the same-origin security policy)浏览器会禁止这种跨域请求。

    v服务端配置

    由于CORS方式实现跨域需要服务端配合设置Header,在springboot中只需要添加以下配置即可,或者在需要支持跨域的方法中直接对response设置header,以下三种方式效果相同。

    第一种:

    @Configuration
    public class WebMvcConfig extends WebMvcConfigurerAdapter {
        /**
         * 重写addCorsMappings方法实现跨域的设置
         * 当然跨域还可以通过在Controller或方法上添加‘@CrossOrigin("http://domain2.com")’的注解实现,不过下面这种方便统一管理
         * 参考:https://docs.spring.io/spring/docs/current/spring-framework-reference/html/cors.html
         */
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/api/**")
                .allowedOrigins("http://a.test.com")  //允许的origin
                .allowedMethods("GET", "POST", "DELETE") //允许的方法
                .allowCredentials(true) //是否允许携带cookie
                .maxAge(3600);
        }
    
        //全局跨域,Enabling CORS for the whole application is as simple as:
        /*@Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/**");
        }*/   
    }

    第二种:

    @RequestMapping
    public Object index(HttpServletRequest request, HttpServletResponse response, @CookieValue(value = "sid", required = false) String sid) {
        response.setHeader("Access-Control-Allow-Origin","http://a.test.com"); //允许跨域的Origin设置
        response.setHeader("Access-Control-Allow-Credentials","true"); //允许携带cookie
        logger.info("cookie sid = " + sid);
        return restTemplateService.someRestCall();
    }

    第三种:

    @RequestMapping
    @CrossOrigin(origins = "http://a.test.com", allowCredentials = "true")
    public Object index(HttpServletRequest request, @CookieValue(value = "sid", required = false) String sid) {
        logger.info("cookie sid = " + sid);
        return restTemplateService.someRestCall();
    }

    v前端调用方式

    1. 原生ajax调用示例:

    var xhr = new XMLHttpRequest();  
    xhr.open("POST", "http://b.test.com/api/rest", true);  
    xhr.withCredentials = true; //支持跨域发送cookies
    xhr.send();

    2. jQuery调用示例:

    $.ajax({
        url: 'http://b.test.com/api/rest',
        dataType: 'json',
        type : 'POST',
        xhrFields: {
            withCredentials: true //是否携带cookie
        },
        crossDomain: true,
        contentType: "application/json",
        success: (res) => {
          console.log(res);
        }
      });

    3. fetch方式

    fetch('http://b.test.com/api/rest', 
      {credentials: 'include'}  //注意这里的设置,支持跨域发送cookies
    ).then(function(res) {
      if (res.ok) {
        res.json().then(function(data) {
          console.log(data.value);
        });
      } else {
        console.log("Looks like the response wasn't perfect, got status", res.status);
      }
    }, function(e) {
      console.log("Fetch failed!", e);
    });

    v注意事项

    值得注意的一点是:服务器端 Access-Control-Allow-Credentials = true时,参数Access-Control-Allow-Origin 的值不能为 '*',必须为具体的origin。

    另外还需要注意:试了一下,cookie的域必须是两个子域的顶级域,才能实现跨域传输。即如果网站A是:a.test.cn,网站B是:b.test.com,那么无论如何都不能实现A携带会话cookie发送跨域请求到网站B上。

    其他参考资料:

    v源码地址

    https://github.com/toutouge/javademosecond/tree/master/hellospringboot


    作  者:请叫我头头哥
    出  处:http://www.cnblogs.com/toutou/
    关于作者:专注于基础平台的项目开发。如有问题或建议,请多多赐教!
    版权声明:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。
    特此声明:所有评论和私信都会在第一时间回复。也欢迎园子的大大们指正错误,共同进步。或者直接私信
    声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是作者坚持原创和持续写作的最大动力!

  • 相关阅读:
    底图与蒙版的过渡效果transition
    消除blur属性的边框
    jquery ajax实例教程和一些高级用法
    常用js正则表达式大全
    HTML5 + JS 调取摄像头拍照下载
    JS运动框架
    JS 实现AJAX封装(只限于异步)
    事件委托详解
    JS 实现随机验证码功能
    利用JS调取电脑摄像头,实现拍照功能
  • 原文地址:https://www.cnblogs.com/toutou/p/9843588.html
Copyright © 2011-2022 走看看