天天看點

跨域通信的幾種方法

1. jsonp工作原理,參考jsonp.js

// 建立ajax【參考網址】https://segmentfault.com/a/1190000006669043

jsonp.js

jsonp = function (url, onsuccess, onerror, charset) {
     var callbackName = util.getName('tt_player');
     window[callbackName] = function () {
         if (onsuccess && util.isFunction(onsuccess)) {
             onsuccess(arguments[0]);
         }
     };
     var script = util.createScript(url + '&callback=' + callbackName, charset);
     script.onload = script.onreadystatechange = function () {
         if (!script.readyState || /loaded|complete/.test(script.readyState)) {
             script.onload = script.onreadystatechange = null;
             // 移除該script的 DOM 對象
             if (script.parentNode) {
                 script.parentNode.removeChild(script);
             }
             // 删除函數或變量
             window[callbackName] = null;
         }
     };
     script.onerror = function () {
         if (onerror && util.isFunction(onerror)) {
             onerror();
         }
     };
     document.getElementsByTagName('head')[0].appendChild(script);
 };
           

加載script标簽的方式,将前端代碼中的 ajax 請求去掉,添加了一個script标簽,标簽的 src 指向了另一個域http://www.abc.com

//告訴服務端結果以jsonp的函數名傳回
    <script src="http://www.abc.com/?data=name&callback=jsonp" charset="utf-8"></script>
//浏覽器下發内容:
    <script type="text/javascript">
    //本地要注冊一個jsonp全局函數将傳回的data執行出來
       jsonp({
           data: {
      
           },
       });
    </script>
           

jQuery 提供了友善使用 JSONP 的方式,雖然類似 ajax 的請求,但是本質是不一樣的,且隻能使用 get 請求,代碼如下:

<!DOCTYPE html>
<html>
<head>
    <title>GoJSONP</title>
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
</head>
<body>
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
<script type="text/javascript">
    $(document).ready(function(){
        $.ajax({
            type : "get",
            async: false,
            url : "http://local.sns.jutouit.com/test.php?id=1",
            dataType: "jsonp",
            jsonp:"callback", //請求php的參數名
            jsonpCallback: "jsonhandle",//要執行的回調函數(參數值)
            success : function(data) {
                alert("age:" + data.age + "  name:" + data.name + "  sex:"+data.sex);
            }
        });
    });	
</script>
</body>
</html>

           

2.利用hash通信

場景是目前頁面 A 通過iframe或frame嵌入了跨域的頁面 B

// 在A中僞代碼如下:
  var B = document.getElementsByTagName('iframe');
  B.src = B.src + '#' + 'data';
  // 在B中的僞代碼如下
  window.onhashchange = function () {
      var data = window.location.hash;
  };
           

3. postMessage

// 視窗A(http:A.com)向跨域的視窗B(http:B.com)發送資訊
  B:window.postMessage('data', 'http://B.com');
  // 在視窗B中監聽message事件
  A:window.addEventListener('message', function (event) {
      console.log(event.origin);//http://A.com
      console.log(event.source);//Awndow
      console.log(event.data);//data
  }, false);
           

4.Websocket

【參考資料】http://www.ruanyifeng.com/blog/2017/05/websocket.html

var ws = new WebSocket('wss://echo.websocket.org');
//建立連接配接
  ws.onopen = function (evt) {
      console.log('Connection open ...');
      //發送消息
      ws.send('Hello WebSockets!');
  };
//接受伺服器消息
  ws.onmessage = function (evt) {
      console.log('Received Message: ', evt.data);
      //關閉連接配接
      ws.close();
  };
//關閉連接配接時的傳回
  ws.onclose = function (evt) {
      console.log('Connection closed.');
  };
           

5. CORS

【參考資料】http://www.ruanyifeng.com/blog/2016/04/cors.html

CORS是一個W3C标準,全稱是“跨域資源共享”(Cross-origin resource sharing)。

它允許浏覽器向跨源伺服器,發出XMLHttpRequest請求,進而克服了AJAX隻能同源使用的限制。實作CORS通信的關鍵是伺服器。隻要伺服器實作了CORS接口,就可以跨源通信。

// url(必選),options(可選)

fetch(’/some/url/’, {

method: ‘get’,

}).then(function (response) {

}).catch(function (err) {
    // 出錯了,等價于 then 的第二個參數,但這樣更好用更直覺
  });
           

繼續閱讀