SpringBoot学习笔记(7)-----CORS支持解决跨域问题
在实际应用开发中,跨域是一个比较常见的问题,解决方法可以用jsonp,frame,cors等,
这里示例的是SpringBoot对CORS的支持的三种实现方式
第一种:配置一种全局的支持,这种方式需要新增一个配置类如下:
package com.wangx.boot.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class CORSConfiguration { @Bean public WebMvcConfigurer webMvcConfigurer () { return new WebMvcConfigurer() { @Override public void addCorsMappings(CorsRegistry registry) {
//允许所有/api/路径下的访问跨域,允许http://localhost:8080的源跨域 registry.addMapping("/api/**").allowedOrigins("http://localhost:8080"); } }; } }
这样在别的服务中想要访问该服务的api路径下的所有资源都会被允许跨域请求,本示例在8080端口的服务下请求8082的服务的资源,请求页面代码如下:
<body> <div onclick="getLabelsGet()">这是一个事件</div> <p id = "data"></p> </body> <script type="text/javascript"> /* 创建 XMLHttpRequest 对象 */ var xmlHttp; function GetXmlHttpObject(){ if (window.XMLHttpRequest){ // code for IE7+, Firefox, Chrome, Opera, Safari xmlhttp=new XMLHttpRequest(); }else{// code for IE6, IE5 xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); } return xmlhttp; } // -----------ajax方法-----------// function getLabelsGet(){ xmlHttp=GetXmlHttpObject(); if (xmlHttp==null){ alert('您的浏览器不支持AJAX!'); return; } var url="http://localhost:8082/api/say?name=jack"; xmlHttp.open("GET",url,true); xmlHttp.onreadystatechange=getOkGet;//发送事件后,收到信息了调用函数 xmlHttp.send(); } function getOkGet(){ if(xmlHttp.readyState==1||xmlHttp.readyState==2||xmlHttp.readyState==3){ // 本地提示:加载中 } if (xmlHttp.readyState==4 && xmlHttp.status==200){ var d= xmlHttp.responseText; // 处理返回结果 var data = document.getElementById("data"); data.innerHTML = d; console.log(d); } } </script>
当点击”这是一个事件“后,访问结果如下:
这样就实现了从一个服务器页面访问另一个服务器之间允许跨域的问题。除了注册一个Bean之外,也可以使用配置类实现WebMvcConfigurer接口来实现跨域,原理一样,都是通过重写addCorsMappings方法来实现跨域的,实现接口的代码如下:
package com.wangx.boot.config; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class CORSConfiguration implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/api/**").allowedOrigins("http://localhost:8080"); } }
第二种:使用@CrossOrigin注解来实现跨域问题,这是最简单的也是可以控制粒度的一种方式,使用注解作用在方法上。则只用该方法允许跨域访问,作用在类上就只有该类中的所有接口允许访问,具体代码如下:
@CrossOrigin注解作用到方法上:
package com.wangx.boot.controller; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/api") public class ApiController { @CrossOrigin(origins = {"http://localhost:8080", "null"}) @RequestMapping("/say") public String say(String name) { System.out.println(name); return "name:" + name + "hello"; } @RequestMapping("/to") public String to(String name) { System.out.println(name); return "name:" + name + "hello"; } }
当在其他服务器页面上访问方法say()时,成功返回数据,访问to时报跨域错误。
@CrossOrigin作用到类上:
package com.wangx.boot.controller; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/api") @CrossOrigin(origins = {"http://localhost:8080", "null"}) public class ApiController { @RequestMapping("/say") public String say(String name) { System.out.println(name); return "name:" + name + "hello"; } @RequestMapping("/to") public String to(String name) { System.out.println(name); return "name:" + name + "hello"; } }
作用到类上时,类中的所有接口均能够被访问别成功返回数据。运行结果与方式一相同