了解跨域之前,我们先来了解如下两个知识点
-
URL组成
URL:协议 + 域名 + 端口号(默认为8080可省略) + 参数
-
浏览器同源策略
所谓同源是指,域名,协议,端口相同。
同源策略是浏览器的行为,是为了保护本地数据不被JavaScript代码获取回来的数据污染,因此拦截的是客户端发出的请求回来的数据接收,即请求发送了,服务器响应了,但是无法被浏览器接收。
不满足同源策略的条件的网页,是不能够互相通信的,这时候就需要我们使用跨域来解决这个问题
1.跨域方法概览
- JSONP
- PostMessage
- domain
- Hash
- 跨域资源共享(CORS)
- WebSocket协议跨域
2. JSONP 跨域
- 通过在界面动态写入 script 标签,设置src属性,将请求以URL参数的形式附加在URL中,并且指定回调函数
- 服务器返回回调函数,并且将数据当作回调函数的参数返回
- 在界面定义回调函数,服务器返回之后会直接调用
代码示例:
<script>
var script = document.createElement('script');
script.type = 'text/javascript';
// 传参一个回调函数名给后端,方便后端返回时执行这个在前端定义的回调函数
script.src = 'http://www.domain2.com:8080/login?user=admin&callback=handleCallback';
document.head.appendChild(script);
// 回调执行函数
function handleCallback(res) {
alert(JSON.stringify(res));
}
</script>
服务器返回如下,返回即执行
handleCallback(someData)
3. postMessage详解
postMessage方法接收两个参数
- data
- origin:发送目标的URL地址
代码示例:
- a.html:
http://www.domain1.com/a.html
<iframe id="iframe" src="http://www.domain2.com/b.html" style="display:none;"></iframe>
<script>
var iframe = document.getElementById('iframe');
iframe.onload = function() {
var data = {
name: 'aym'
};
// 向domain2传送跨域数据
iframe.contentWindow.postMessage(JSON.stringify(data), 'http://www.domain2.com');
};
// 接受domain2返回数据
window.addEventListener('message', function(e) {
alert('data from domain2 ---> ' + e.data);
}, false);
</script>
- b.html:
http://www.domain2.com/b.html
<script>
// 接收domain1的数据
window.addEventListener('message', function(e) {
alert('data from domain1 ---> ' + e.data);
var data = JSON.parse(e.data);
if (data) {
data.number = 16;
// 处理后再发回domain1
window.parent.postMessage(JSON.stringify(data), 'http://www.domain1.com');
}
}, false);
</script>
4. domain
此方法仅限主域相同,子域不同的跨域应用场景
实现方式:两个页面都通过js强制设置 document.domain为基础主域,就实现了同域
代码示例:
- 父窗口:
http://www.domain1.com/a.html
<iframe id="iframe" src="http://child.domain.com/b.html"></iframe>
<script>
document.domain = 'domain.com';
var user = 'admin';
</script>
- 子窗口:
http://child.domain2.com/b.html
<script>
document.domain = 'domain.com';
// 获取父窗口中变量
alert('get js data from parent ---> ' + window.parent.user);
</script>
5. CORS
普通跨域请求:只服务端设置Access-Control-Allow-Origin即可,前端无须设置
6. WebSocket协议跨域
前端代码示例
<div>user input:<input type="text"></div>
<script src="https://cdn.bootcss.com/socket.io/2.2.0/socket.io.js"></script>
<script>
var socket = io('http://www.domain2.com:8080');
// 连接成功处理
socket.on('connect', function() {
// 监听服务端消息
socket.on('message', function(msg) {
console.log('data from server: ---> ' + msg);
});
// 监听服务端关闭
socket.on('disconnect', function() {
console.log('Server socket has closed.');
});
});
document.getElementsByTagName('input')[0].onblur = function() {
socket.send(this.value);
};
</script>
参考文章: