SpringBoot(十三)CORS方式实现跨域

Posted 请叫我头头哥

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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);
});

以上是关于SpringBoot(十三)CORS方式实现跨域的主要内容,如果未能解决你的问题,请参考以下文章

springboot解决跨域问题(Cors)

SpringBoot rest-api+Vue CORS跨域.md

Spring Boot 2中对于CORS跨域访问的快速支持

SpringBoot跨域(CORS)支持:注解@CrossOrigin

SpringBoot 中通过 CORS 解决跨域问题

SpringBoot跨域CORS设置:实现根据来源地址返回对应的Access-Control-Allow-Origin允许网址