一,什么是CORS?
1,CORS(跨域资源共享)(CORS,Cross-origin resource sharing),
它是一个 W3C 标准中浏览器技术的规范,
它允许浏览器向非同一个域的服务器发送XMLHttpRequest请求,
避免了Ajax只能在同一个域的服务器下使用的限制
2,什么是跨域问题?
跨域问题指的是浏览器不能执行其他网站的脚本.
它是由浏览器的同源策略造成的,因为浏览器对javascript施加有安全限制.
当前所有的浏览器都实行同源策略,所谓的同源指的是
- 协议相同
- 域名相同
- 端口相同
浏览器执行javascript脚本时,会检查这个脚本属于哪个页面,
如果不是同源页面,就不会被执行.
说明:如果是指向相同ip的域名,也会被认为是跨域,例如:
127.0.0.1 和 localhost,也会被浏览器认为发生了跨域
3,允许跨域时浏览器的返回信息:

可以看到其中的:Access-Control-Allow-Origin: http://127.0.0.1:1999
禁止跨域时浏览器的返回信息:

4,在生产环境中要注意的地方:
互联网搜索到的很多例子直接允许所有的域访问所有的路径,
这是绝对不能做的,
因为在互联网上被这样访问会引发安全问题
必须指定明确的路径和明确的域
说明:刘宏缔的架构森林是一个专注架构的博客,地址:https://www.cnblogs.com/architectforest
对应的源码可以访问这里获取: https://github.com/liuhongdi/
说明:作者:刘宏缔 邮箱: 371125307@qq.com
二,演示项目的说明
1,项目地址:
https://github.com/liuhongdi/corsconfig
2,项目功能说明:
演示了两种解决cors问题的方法:
WebMvcConfigurer配置
@CrossOrigin注解
3,项目结构;如图:

三,java代码说明
1,CorsConfig.java
@Configuration public class CorsConfig implements WebMvcConfigurer { //指定允许跨域的多个域 private static final String[] ALLOWED_ORIGINS = {"http://www.baidu.com","http://127.0.0.1:81","https://blog.csdn.net"}; @Bean public WebMvcConfigurer corsConfigurer() { //添加跨域的cors配置 return new WebMvcConfigurer() { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/goods/**"). //可以被跨域的路径,/**表示无限制, allowedOrigins(ALLOWED_ORIGINS). //允许跨域的域名,如果值为*,则表示允许任何域名使用 allowedMethods("*"). //允许任何方法,值可以为: "GET", "POST" ... allowedHeaders("*"). //允许任何请求头 allowCredentials(true). //允许带cookie信息 exposedHeaders(HttpHeaders.SET_COOKIE).maxAge(3600L); //maxAge(3600):表示3600秒内,不需要再发送预检验请求,是结果可以缓存的时长 } }; } }
说明:用addCorsMapping方法添加对跨域路径/允许跨域的域名等的规则
2,HomeController.java
@RestController @RequestMapping("/home") public class HomeController { //允许跨域多个值 @CrossOrigin(origins = {"http://127.0.0.1:1999","http://cas.baidu.com","http://do.baidu.com"},maxAge = 3600) @GetMapping @RequestMapping("/home") public String home() { return "this is /home/home"; } //允许跨域,只有一个域 //只写@CrossOrigin 表示允许所有域访问 @CrossOrigin("http://127.0.0.1:1999") @GetMapping @RequestMapping("/index") public String index() { return "this is /home/index"; } }
演示用@CrossOrigin注解为指定的方法或类来指定跨域的规则
3,GoodsController.java
@RestController @RequestMapping("/goods") public class GoodsController { @GetMapping @RequestMapping("/one") public String one() { return "this is /goods/one"; } }
供测试用,CorsConfig.java中配置了它的跨域规则
四, javascript代码说明
1,page81.html
<html xmlns="http://www.w3.org/1999/xhtml"> <head> <title >标题</title> <meta charset="utf-8" /> <script type="text/javascript" language="JavaScript" src="/jquery-1.6.2.min.js"></script> </head> <body> <div id="content" style="800px;"> <div style="250px;float:left;font-size: 16px;" ></div> <div style="550px;float:left;"> <!--====================main begin=====================--> <a href="javascript:get_home()" >访问8080:/home/home</a><br/> <a href="javascript:get_goods()" >访问8080:/goods/one</a> <!--====================main end=====================--> </div> </div> <script> //访问8080:/goods/one function get_goods(){ $.ajax({ type:"GET", url:"http://127.0.0.1:8080/goods/one", //返回数据的格式 datatype: "text",//"xml", "html", "script", "json", "jsonp", "text". processData: false, contentType: false, //成功返回之后调用的函数 success:function(data){ alert(data); }, //调用执行后调用的函数 complete: function(XMLHttpRequest, textStatus){ }, //调用出错执行的函数 error:function(jqXHR,textStatus,errorThrown){ console.log(jqXHR); console.log(textStatus); console.log(errorThrown); } }); } //访问8080:/home/home function get_home(){ $.ajax({ type:"GET", url:"http://127.0.0.1:8080/home/home", //返回数据的格式 datatype: "text",//"xml", "html", "script", "json", "jsonp", "text". processData: false, contentType: false, //成功返回之后调用的函数 success:function(data){ alert(data); }, //调用执行后调用的函数 complete: function(XMLHttpRequest, textStatus){ }, //调用出错执行的函数 error:function(jqXHR,textStatus,errorThrown){ console.log(jqXHR); console.log(textStatus); console.log(errorThrown); } }); } </script> </body> </html>
说明:把这个页面放到本地端口为81的域下
2,page1999.html
<html xmlns="http://www.w3.org/1999/xhtml"> <head > <title >标题</title> <meta charset="utf-8" /> <script type="text/javascript" language="JavaScript" src="/jquery-1.6.2.min.js"></script> </head> <body> <div id="content" style="800px;"> <div style="250px;float:left;font-size: 16px;" ></div> <div style="550px;float:left;"> <!--====================main begin=====================--> <a href="javascript:get_index()" >访问8080:/home/index</a><br/> <a href="javascript:get_home()" >访问8080:/home/home</a><br/> <a href="javascript:get_goods()" >访问8080:/goods/one</a> <!--====================main end=====================--> </div> </div> <script> //访问8080:/goods/one function get_goods(){ $.ajax({ type:"GET", url:"http://127.0.0.1:8080/goods/one", //返回数据的格式 datatype: "text",//"xml", "html", "script", "json", "jsonp", "text". processData: false, contentType: false, //成功返回之后调用的函数 success:function(data){ alert(data); }, //调用执行后调用的函数 complete: function(XMLHttpRequest, textStatus){ }, //调用出错执行的函数 error:function(jqXHR,textStatus,errorThrown){ console.log(jqXHR); console.log(textStatus); console.log(errorThrown); } }); } //访问8080:/home/index function get_index(){ $.ajax({ type:"GET", url:"http://127.0.0.1:8080/home/index", //返回数据的格式 datatype: "text",//"xml", "html", "script", "json", "jsonp", "text". processData: false, contentType: false, //成功返回之后调用的函数 success:function(data){ alert(data); }, //调用执行后调用的函数 complete: function(XMLHttpRequest, textStatus){ }, //调用出错执行的函数 error:function(jqXHR,textStatus,errorThrown){ console.log(jqXHR); console.log(textStatus); console.log(errorThrown); } }); } //访问8080:/home/home function get_home(){ $.ajax({ type:"GET", url:"http://127.0.0.1:8080/home/home", //返回数据的格式 datatype: "text",//"xml", "html", "script", "json", "jsonp", "text". processData: false, contentType: false, //成功返回之后调用的函数 success:function(data){ alert(data); }, //调用执行后调用的函数 complete: function(XMLHttpRequest, textStatus){ }, //调用出错执行的函数 error:function(jqXHR,textStatus,errorThrown){ console.log(jqXHR); console.log(textStatus); console.log(errorThrown); } }); } </script> </body> </html>
说明:把这个页面放到本地端口为1999的域下
五,效果测试
1,访问:
http://127.0.0.1:1999/page1999.html
效果:
测试可以发现:
/home/index,/home/home允许访问,
而/goods/one不允许访问,因为没有允许从127.0.0.1:1999访问到8080的java项目的规则
2,访问:
http://127.0.0.1:81/page81.html
效果:
可以测试发现:
访问到 /goods/one没有问题,
访问到/home/home会报错,
因为没有允许从127.0.0.1:81访问到8080的java项目的规则
六,查看spring boot版本
. ____ _ __ _ _ /\ / ___'_ __ _ _(_)_ __ __ _ ( ( )\___ | '_ | '_| | '_ / _` | \/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v2.3.2.RELEASE)