跨域是什么
跨域:指浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对javascript施加的安全限制
同源策略:是指协议、域名、端口都要相同,其中有一个不同都会产生跨域
例如:a页面想获取b页面资源,如果a、b页面的协议、域名、端口、子域名不同,所进行的访问行动都是跨域的,而浏览器为了安全问题一般都限制了跨域访问,也就是不允许跨域请求资源。
注意:跨域限制访问,其实是浏览器的限制,理解这一点很重要。
模拟跨域
要解决跨域问题,我们就得先模拟一个跨域情景。新建Spring Boot项目,并引如下依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
创建DemoController类:
@Controller
public class DemoController {
@RequestMapping("index")
public String index() {
return "index";
}
@GetMapping("/hello")
@ResponseBody
public String hello() {
return "hello";
}
}
然后在resources/templates下新建index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>跨域测试</title>
<script src="http://libs.baidu.com/jquery/1.11.3/jquery.min.js"></script>
</head>
<body>
<div id="hello"></div>
</body>
<script>
$(function () {
$.get("http://lconcise.top:9090/hello", function (data) {
$("#hello").text(data);
})
})
</script>
</html>
编辑本地hosts文件,将域名lconcise.top映射到127.0.0.1上:
启动项目访问http://127.0.0.1:9090/index,会发现页面并没有成功显示hello,并且F12观察浏览器控制台会发现其报错了:
image.png
这是因为我们在http://127.0.0.1:9090/index域名下试图访问http://lconcise.top:9090/index下的hello接口,这就存在跨域问题。
解决跨域(三种方式)
1. SpringBoot中处理跨域
参考我以前写的一篇文章SpringBoot 中处理跨域
2. nginx代理
image.png- 当用户发送localhost:80时被nginx转发到web服务
- 当界面请求接口以/api开头,就会被nginx转发到后台服务
3. JSONP
一个众所周知的问题,Ajax直接请求普通文件存在跨域无权限访问的问题,甭管你是静态页面、动态网页、web服务、WCF,只要是跨域请求,一律不准。
Web页面上调用js文件时则不受是否跨域的影响(不仅如此,我们还发现凡是拥有”src”这个属性的标签都拥有跨域的能力,比如<\script>、<\img>、<\iframe>)。
于是可以判断,当前阶段如果想通过纯web端(ActiveX控件、服务端代理、属于未来的HTML5之Websocket等方式不算)跨域访问数据就只有一种可能,那就是在远程服务器上设法把数据装进js格式的文件里,供客户端调用和进一步处理。
恰巧我们已经知道有一种叫做JSON的纯字符数据格式可以简洁的描述复杂数据,更妙的是JSON还被js原生支持,所以在客户端几乎可以随心所欲的处理这种格式的数据。
这样子解决方案就呼之欲出了,web客户端通过与调用脚本一模一样的方式,来调用跨域服务器上动态生成的js格式文件(一般以JSON为后缀),显而易见,服务器之所以要动态生成JSON文件,目的就在于把客户端需要的数据装入进去。
客户端在对JSON文件调用成功之后,也就获得了自己所需的数据,剩下的就是按照自己需求进行处理和展现了,这种获取远程数据的方式看起来非常像AJAX,但其实并不一样。
为了便于客户端使用数据,逐渐形成了一种非正式传输协议,人们把它称作JSONP,该协议的一个要点就是允许用户传递一个callback参数给服务端,然后服务端返回数据时会将这个callback参数作为函数名来包裹住JSON数据,这样客户端就可以随意定制自己的函数来自动处理返回数据了。
jsonp的核心则是动态添加
参考博文:
https://www.jianshu.com/p/8fa2acd103ea
https://blog.csdn.net/hansexploration/article/details/80314948
网友评论