javascript 跨域雙向通信方案,通過postMessage和window.name實現


更新:

最近項目使用在node-webkit中用於iframe flash的調用,有一個json版本,設計方面還是有些缺陷,沒有設計成mian,client可以1對多創建的方式,考慮重構

此方案在IE6,7下面通過window.name實現跨域信息的傳遞,會導致一系列的BUG,項目中需要兼容的話,請使用以下技術處理

http://www.alloyteam.com/2013/11/the-second-version-universal-solution-iframe-cross-domain-communication

前言:

專門從事js工作其實也有1年時間了,水平一般。獲取前端相關的知識,主要通過 司徒正美的博客 和 司徒正美的QQ群-javascript羅浮宮。

在去年的項目中,做消息推送的時候,由於推送服務部署在一個獨立的服務上,后來試了一些方案,

最后是通過window.name和postMessage結合的方式解決跨域問題,從而實現消息推送(AJAX 的長輪詢).

最近項目比較空,特地花了時間整理了下代碼。當然跨域的實現,還是首推JSONP的方式

作用:

我們作為客戶端,開放相關API給其他第3方進行訪問

(如果該js真的能解決你的需求,希望能支持下,讓更多人得到方便)。

原理:

相關原理可以參考 http://js8.in/752.html,對於通過name的方式,本js加入了代理頁(about:blank),不會污染主端window.name,結構下圖

功能:

1.實現main.html和client.html之間的雙向通信,通過提供相關Command。

2.通過callback機制,可以方便的對返回的數據進行相應的處理。

3.多參數支持,參數支持字符串,數字,通過加載JSON的js,支持object,數組

例子:

  https://github.com/legu2009/cross-domain-javascript

  github上有相關例子的環境,可以安裝nodejs,進行調試。(去掉注釋,可支持json格式,例子簡化了下,主要演示一個主端向客戶端調用API的過程).

     mainAPI.html

View Code
<body>
</body>
<!--script type="text/javascript" src="http://localhost:9099/json2.js"></script-->
<script type="text/javascript" src="http://localhost:9099/crossDomain.js"></script>
<script>
(function () {
    var host = '  main.html';//window.location.host;
    var slice = Array.prototype.slice;
    typeof console == "undefined" && (console = {
        log: function () {
            alert(slice.call(arguments).join(':'));
        }
    });
    var config = {
        clientUrl: "http://localhost:9098/clientAPI.html"
        //,aboutBlank: 'NO'
        //,isSameDomain: false
    };
    var crossDomain = getCrossDomain(config);
    /*
    crossDomain.message.set({
        params2str: function () {
            return JSON.stringify(slice.call(arguments, 0));
        },
        str2params: function (str) {
            return JSON.parse(str);
        }
    });*/
    
    function callback (str) {
        var str = slice.call(arguments).join(',') + '=>>';
        return function () {
            console.log(host+'@',str+slice.call(arguments).join(','));
        }
        //console.log(host+':'+slice.call(arguments, 0).join(','));
    }
    crossDomain.message.send('clientCall','hello,i\'m main');//調用命令
    crossDomain.message.send('clientCall','your name',callback('your name'));//調用命令,並顯示返回值
    crossDomain.message.send('clientCall','your mail',callback('your mail'));
    crossDomain.message.send('clientCall','your mail', 'the date',{'aa':123},callback('your mail', 'the date',{'aa':123}));//多參數支持

})();
</script>

    clientAPI.html

View Code
<body>
</body>
<!--script type="text/javascript" src="http://localhost:9099/json2.js"></script-->
<script type="text/javascript" src="http://localhost:9099/crossDomain.js"></script>
<script>
(function () {
    var host = 'client.html';//window.location.host;
    var slice = Array.prototype.slice;
    typeof console == "undefined" && (console = {
        log: function () {
            alert(slice.call(arguments).join(':'));
        }
    });
    var config = {
        clientUrl: "http://localhost:9098/clientAPI.html"
        //,aboutBlank: 'NO'
        //,isSameDomain: false
    };
    var crossDomain = getCrossDomain(config);
    /*
    crossDomain.message.set({
        params2str: function () {
            return JSON.stringify(slice.call(arguments, 0));
        },
        str2params: function (str) {
            return JSON.parse(str);
        }
    });*/
    
    var apiMap = {
        'your name': 'guwei',
        'your mail': '89415119@qq.com',
        'the date': new Date().toString()
    }
    crossDomain.clientCommand.add('clientCall', function(str, callback) {
        console.log(host+'@','clientCall:',slice.call(arguments));
        try {
            console.log(host+'@','aa:'+arguments[2].aa);//判斷JSON支持
        } catch (e) {}
        var callback = arguments[arguments.length-1];
        var ary = slice.call(arguments, 0, -1);
        //console.log(host+':'+ary.join(','));
        for (var i =0;i<ary.length;i++) {
            ary[i] = apiMap[ary[i]]||ary[i];
        }
        callback.apply(null,ary);//即使有的API沒有數據返回,也需要執行下callback
    });
})();
</script>

 

執行結果:

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM