同源是指“协议”、“端口”、“域名”均相同,如果其中有一个不同,就会导致跨域。
非同源的话,以下的行为会被限制
(1) Cookie、LocalStorage 和 IndexDB 无法读取。
(2) DOM 无法获得。
(3) AJAX 请求不能发送。
有时我们想打破这些限制,就需要进行跨域通信,常用的跨域通信又以下几种方式:
1.JSONP:利用script标签的src可以访问任意远程脚本,没有同源的限制。
将要访问的后端接口地址复制给script的src属性,加上callback;后端该接口返回一段JS代码,执行callback函数;前端页面需要有相应的callback函数。
HTML页面:
<script src="http://www.abc.com/service.php?data=name&callback=jsonp" charset="utf-8"></script>
<script type="text/javascript">
function jsonp(data){
console.log(data);
}
</script>
后端PHP页面
<?php
$data = array(
'age' => 20,
'name' => '张三',
);
$callback = $_GET['callback'];
echo $callback."(".json_encode($data).")";
return;
?>
JSONP原理参考https://blog.csdn.net/u011897301/article/details/52679486
- JSONP的优点:兼容性好,在更加古老的浏览器中都可以运行,不需要XMLHttpRequest或ActiveX的支持
- JSONP的缺点:只支持GET请求而不支持POST等其它类型的HTTP请求
2.hash
此种情况适用于前页面 A 通过iframe或frame嵌入了跨域的页面 B
// 在A中伪代码如下:
var B = document.getElementsByTagName('iframe');
B.src = B.src + '#' + data1;
// 在B中的伪代码如下
window.onhashchange = function () {
var data = window.location.hash; //此处需对取得的data进行处理,解析出从页面A中传递过来的数据
};
3.postMessage
// 窗口A(http:A.com)向跨域的窗口B(http:B.com)发送信息
window.postMessage('data', 'http://B.com');
// 在窗口B中监听
function receiveMessage(event)
{
//event.origin 消息源
// event.source
// event.data 是发送给当前页面的消息'data'
}
window.addEventListener('message', receiveMessage, false);
postMessage参考https://developer.mozilla.org/zh-CN/docs/Web/API/Window/postMessage
缺点:需注意浏览器的兼容性,Internet Explorer 8+, chrome,Firefox , Opera 和 Safari支持该方法。
4.WebSockect
参考阮一峰老师的博客http://www.ruanyifeng.com/blog/2017/05/websocket.html
var ws = new WebSocket('ws://localhost:8080');
ws.onopen = function () {
ws.send('Hello Server!');
}
ws.onmessage = function(event) {
var data = event.data;
// 处理数据
};
ws.onclose = function (event) {
console.log('Connection closed.');
};
5.CORS
CORS需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。