同源是指“协议”、“端口”、“域名”均相同,如果其中有一个不同,就会导致跨域。

非同源的话,以下的行为会被限制

(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