同源是指“协议”、“端口”、“域名”均相同,如果其中有一个不同,就会导致跨域。
非同源的话,以下的行为会被限制
(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。
参考阮一峰老师的博客 http://www.ruanyifeng.com/blog/2016/04/cors.html