在了解SpringBoot使用CROS实现跨域问题之前,我们先聊聊什么是跨域
?
举个简单例子:比如我是中国人,我想出国去另一个国家,但是第一次出国要办理一系列手续,办理完手续后才能出国去到另一个国家,这是现实中的跨域问题,同理,作为开发人员,我们日常的系统资源访问多多少少也会存在跨域问题,比如我的网站要获取另一个网站的资源,但是这是两个不同的站点,这样我们要获取所需资源就需要跨域。
为什么会有跨域?
说到跨域问题这就不得不说说同源策略,同源策略是浏览器的一种安全策略,它用于限制一个origin的文档或者它加载的脚本如何能与另一个源的资源进行交互。它能帮助阻隔恶意文档,减少可能被攻击的媒介。当然这个解释比较官方,具体可点击这里
查看,简单点就是为了网络安全,所谓同源就是两个网页协议、域名、端口都相同即是同源,举个例子如URL:http://store.company.com/dir/page.html
URL | 结果 | 原因 |
---|---|---|
http://store.company.com/dir2/other.html | 同源 | 只有路径不同 |
http://store.company.com/dir/inner/another.html | 同源 | 只有路径不同 |
https://store.company.com/secure.html | 不同源 | 协议不同 |
http://store.company.com:81/dir/etc.html | 不同源 | 端口不同 ( http:// 默认端口是80) |
http://news.company.com/dir/other.html | 不同源 | 主机不同 |
为了解决这一问题,前端通常使用JSONP
进行实现,但是JSONP只能发GET
请求,这里就不多聊了,那么今天就带大家聊聊,怎样在后端通过SpringBootj结合CROS
实现跨域?
更多CROS可以看看阮一峰老师的跨域资源共享 CORS 详解
SringBoot中使用CROS解决跨域问题
创建两个SpringBoot项目,分别设置端口为8080和8081:
cros1项目为被请求数据的一方,端口为默认80
编写请求接口如下:
@RestController
public class HelloController {
@GetMapping("/hello")
public String hello(){
return "hello";
}
}
此时被请求接口并未做任何处理
cros2项目为发起数据请求方,端口为8081
编写ajax
请求,并访问http://localhost:8080/hello
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="jquery-1.12.4.js"></script>
</head>
<body>
<div id="msg"></div>
<input type="button" onclick="getData()" value="请求数据">
</body>
<script>
function getData() {
$.get("http://localhost:8080/hello",function (msg) {
$("#msg").text(msg);
})
}
</script>
</html>
在application.properties中修改端口
server.port=8081
编写完成后,分别启动两个项目,通过cors2发起请求:
打开控制台,点击请求数据发现会报如下错误,No 'Access-Control-Allow-Origin' header is present on the requested resource.
原因是存在跨域,http://localhost:8080/hello这个站点不允许被访问,那么,我们对这个接口进行修改如下:
在允许跨域访问的接口上或类上添加@CrossOrigin
注解,配置origins
允许被访问的地址
@RestController
public class HelloController {
@GetMapping("/hello")
//在允许跨域访问的接口上或类上添加@CrossOrigin注解,配置origins允许被访问的地址
@CrossOrigin(origins = "http://localhost:8081")
public String hello(){
return "hello";
}
}
修改完成后,重启项目然后再次访问
跨域问题解决了,但是又衍生出了一个新问题,要是所有的接口都要允许跨域,每个上面都添加@CrossOrigin配置允许访问的地址,这不是很麻烦吗,有没有全局配置?
SpringBoot配置全局CROS
将之前的@CrossOrigin注释掉,新建配置类WebMvcConfig,如下:
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**") //拦截所有路径
.allowedOrigins("http://localhost:8081") //允许跨域的地址
.allowedHeaders("*") //允许的头信息,*表示所有
.allowedMethods("*"); //允许的方法,GET PUT HEAD 等等,* 表示所有
}
}
配置好全局配置后,重新访问,同样支持跨域,SpringBoot中使用CROS实现跨域请求就介绍到这里了。