讲跨域之前,首先要了解,为什么要跨域
跨域是因为同源策略
使用过 Ajax 的同学都知道其便利性,可以在不向服务端提交完整页面的情况下,实现局部刷新,在当今 SPA 应用普遍使用,但是浏览器处于对安全方面的考虑,不允许跨域调用其它页面的对象,这对于我们在注入 iframe 或是 ajax 应用上带来不少麻烦。
简单来说,只有当协议,域名,端口号相同的时候才算是同一个域名,否则,均认为需要做跨域处理。
image
关于跨域技巧大致可以分为 iframe 跨域和 API 跨域请求,iframe用的不多,讲讲api跨域
最常见的3中跨域方式:JSONP CORS 服务端代理
1. JSONP
只要说到跨域,就必须聊到 JSONP,JSONP 全称为:JSON with padding,可用于解决老版本浏览器的跨域数据访问问题。
由于 web 页面上调用 js 文件不受浏览器同源策略的影响,所以通过 script 标签可以进行跨域请求:
首先前端需要先设置好回调函数,并将其作为 url 的参数。
服务端接收到请求后,通过该参数获取到回调函数名,并将数据放在参数中将其返回
收到结果后因为是 script 标签,所以浏览器会当做是脚本进行运行,从而达到跨域获取数据的目的
jsonp 之所以能够跨域的关键在于页面调用 JS 脚本是不受同源策略的影响,相当于向后端发起一条 http 请求,跟后端约定好函数名,后端拿到函数名,动态计算出返回结果并返回给前端执行 JS 脚本,相当于是一种 "动态 JS 脚本"
//前端逻辑:
// jsonp/index.html
<script>
function jsonpCallback(data) {
alert('获得 X 数据:' + data.x);
}
</script>
<script src="http://127.0.0.1:3000?callback=jsonpCallback"></script>
优点:
它不像XMLHttpRequest 对象实现 Ajax 请求那样受到同源策略的限制
兼容性很好,在古老的浏览器也能很好的运行
不需要 XMLHttpRequest 或 ActiveX 的支持;并且在请求完毕后可以通过调用 callback 的方式回传结果。
缺点:
它支持 GET 请求而不支持 POST 等其它类行的 HTTP 请求。
它只支持跨域 HTTP 请求这种情况,不能解决不同域的两个页面或 iframe 之间进行数据通信的问题
无法捕获 Jsonp 请求时的连接异常,只能通过超时进行处理
2. CORS:
CORS 是一个 W3C 标准,全称是"跨域资源共享"(Cross-origin resource sharing)它允许浏览器向跨源服务器,发出 XMLHttpRequest 请求,从而克服了 ajax 只能同源使用的限制。
CORS 需要浏览器和服务器同时支持才可以生效,对于开发者来说,CORS 通信与同源的 ajax 通信没有差别,代码完全一样。浏览器一旦发现 ajax 请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。
因此,实现 CORS 通信的关键是服务器。只要服务器实现了 CORS 接口,就可以跨域通信。
//前端逻辑很简单,只要正常发起 ajax 请求即可:
// cors/index.html
<script>
const xhr = new XMLHttpRequest();
xhr.open('GET', 'http://127.0.0.1:3000', true);
xhr.onreadystatechange = function() {
if(xhr.readyState === 4 && xhr.status === 200) {
alert(xhr.responseText);
}
}
xhr.send(null);
</script>
关键是在于设置相应头中的 Access-Control-Allow-Origin,该值要与请求头中 Origin 一致才能生效,否则将跨域失败。
CORS 的优缺点:
- 使用简单方便,更为安全
- 支持 POST 请求方式
- CORS 是一种新型的跨域问题的解决方案,存在兼容问题,仅支持 IE 10 以上
这里只是对 CORS 做一个简单的介绍,如果想更详细地了解其原理的话,可以看看下面这篇文章:跨域资源共享 CORS 详解 - 阮一峰的网络日志
3. 服务端代理:
服务器代理,顾名思义,当你需要有跨域的请求操作时发送请求给后端,让后端帮你代为请求,然后最后将获取的结果发送给你。
网友评论