一. 跨域问题
一.一 浏览器的同源策略
同源策略是由 Netscape 提出的一个著名的安全策略,它是浏览器最核心也最基本的安全功能,
现在所有支持 JavaScript 的浏览器都会使用这个策略。
所谓同源是指协议、域名以及端口要相同。
同源策略是基于安全方面的考虑提出来的,这个策略本身没问题,但是我们在实际开发中,
由于各种原因又经常有跨域的需求,传统的跨域方案是 JSONP,JSONP 虽然能解决跨域但是有一个很大的局限性,
那就是只支持 GET 请求,
不支持其他类型的请求,而今天我们说的 CORS(跨域源资源共享)
(CORS,Cross-origin resource sharing)是一个 W3C 标准,
它是一份浏览器技术的规范,提供了 Web 服务从不同网域传来沙盒脚本的方法,以避开浏览器的同源策略,
这是 JSONP 模式的现代版。
一.二 验证同源策略,复现跨域问题
创建两个项目,一个是服务的提供者, SpringBoot_Cors_Provider (服务提供者),
SpringBoot_Cors_Consumer (服务的消费者),
这两个项目均是 SpringBoot整合Thymeleaf 的相关项目
一.二.一 服务提供者
端口号是 8081, 服务路径为: Cors_Provider
一.二.一.一 提供服务
@Controller public class InfoController { /** * 跳转到主页 * @param model * @return */ @RequestMapping("/index") public String info(Model model){ return "index"; } @GetMapping("/findById") @ResponseBody public User findById(Integer id){ User user=new User(); user.setId(id); user.setName("两个蝴蝶飞"); user.setDescription("Get 提交 跨域问题"); return user; } @PostMapping("/addUser") @ResponseBody public User addUser(@RequestBody User user){ //补充信息 user.setName("岳泽霖"); user.setDescription("POST提交 跨域问题"); return user; } }
一.二.一.二 首页 index.html
<body class="container"> <!--展示信息--> 提供者: <p id="message" style="margin-top:200px;"></p> <button type="button" class="btn btn-success" id="get_submit">Get获取信息</button> <button type="button" class="btn btn-success" id="post_submit">Post获取信息</button> <script type="text/javascript" src="webjars/jquery/3.5.1/jquery.js"></script> <script type="text/javascript" src="webjars/bootstrap/3.4.1/js/bootstrap.js"></script> <script> $(function(){ }) //get请求 $("#get_submit").click(function(){ $.ajax({ async:false, type:"get", url:"findById?id=1", success:function(data){ $("#message").text( JSON.stringify(data) ); } }); }); //post 请求 $("#post_submit").click(function(){ $.ajax({ async:false, type:"post", url:"addUser", data:JSON.stringify({ "id":2 }), dataType:"json", contentType:"application/json;charset=utf-8", success:function(data){ $("#message").text( JSON.stringify(data) ); } }); }); </script> </body>
一.二.一.三 服务提供者验证
get 请求
post 请求
一.二.二 服务消费者
端口号是 8082, 项目路径是 Cors_Consumer
只需要一个前端的静态页面 index.html 和 一个跳转方法即可。
一.二.二.一 controller层跳转
@Controller public class InfoController { /** * 普通展示 * @param model * @return */ @RequestMapping("/index") public String info(Model model){ return "index"; } }
一.二.二.二 首页 index.html
<body class="container"> <!--展示信息--> 消费者: <p id="message" style="margin-top:200px;"></p> <button type="button" class="btn btn-success" id="get_submit">Get获取信息</button> <button type="button" class="btn btn-success" id="post_submit">Post获取信息</button> <script type="text/javascript" src="webjars/jquery/3.5.1/jquery.js"></script> <script type="text/javascript" src="webjars/bootstrap/3.4.1/js/bootstrap.js"></script> <script> $(function(){ }) //get请求 $("#get_submit").click(function(){ $.ajax({ async:false, type:"get", //填写具体的路径 url:"http://localhost:8081/Cors_Provider/findById?id=1", success:function(data){ $("#message").text( JSON.stringify(data) ); } }); }); //post 请求 $("#post_submit").click(function(){ $.ajax({ async:false, type:"post", //填写具体的路径 url:"http://localhost:8081/Cors_Provider/addUser", data:JSON.stringify({ "id":2 }), dataType:"json", contentType:"application/json;charset=utf-8", success:function(data){ $("#message").text( JSON.stringify(data) ); } }); }); </script> </body>
一.二.二.三 跨域请求
CORS error
端口号不同,不属于同源,所以无法访问。
注意,是浏览器无法访问, 如果是用 Postman 的话,是可以正常请求通过的
如果是后端之间通过 RestTemplate, Feign 等相互调用,也是可以访问到的。
(所以,不要说,我接口 postman没有问题啊,你前端怎么访问不到呢)