html5 postMessage 实现类似 sendMessage 的同步效果,支持跨域

实现一个客户端发送 “save 一个答案,在获取答案, 跨域的另一个页面中,回调返回”3“的场景。

客户端:请在 http://127.0.0.1/pk/index.html 打开

<html>
<meta charset="utf-8" />

<head>
    <title>
        测试页面, http://127.0.0.1/pk/index.html
    </title>

</head>

<body>

    <iframe id="database" src="http://localhost/pk/localStorage.html">

    </iframe>
    <script type="text/javascript">

        function SyncMessageClient(win, domain) {
            var funName = 0;
            var scope = {};
            function getNextCallbackName(callback) {
                var retfunc = "cb_" + (funName++);
                scope[retfunc] = function () {
                    callback.apply(win, arguments);
                }

                return retfunc;
            }

            window.addEventListener("message", function (ev) {
                var rdata = JSON.parse(ev.data);
                var fn = scope[rdata.fn];

                fn(rdata.args);
                delete scope[rdata.fn];
            })

            this.sendMessage = function (targetWindow, data, callback, targetDomain) {
                var callData = { data: data, fn: getNextCallbackName(callback) };
                targetWindow.postMessage(JSON.stringify(callData), targetDomain);
            }
        };

        function SyncMessageServer(win, domain, onSendMessage) {
            window.addEventListener("message", function (ev) {
                var json = JSON.parse(ev.data);
                var fn = json.fn;
                console.dir(json);
                ev.data = JSON.stringify(json);
                var result = onSendMessage(ev);
                ev.source.postMessage(
                    JSON.stringify({ fn: fn, args: [result] }), "*");

            });
        }



        var objSyncMsg = new SyncMessageClient(window, "*");

        function save(data, callback, domain) {
            var databaseWindow = document.getElementById("database").contentWindow;
            objSyncMsg.sendMessage(databaseWindow, { cmd: "save", q: "1+1=?" ,a:"2"}, function (ok) {
                
            }, "*");



        }

        function send(data, callback, domain) {
            var databaseWindow = document.getElementById("database").contentWindow;
            objSyncMsg.sendMessage(databaseWindow, { cmd: "query", q: "1+1=?" }, function (ok) {
                alert(ok);
            }, "*");



        }
    </script>

    <input type="button" value="save me" onclick="save()"></input>
    <input type="button" value="query me" onclick="send()"></input>
</body>

</html>

  

服务的实现:

<html>
<meta charset="utf-8" />

<head>
    <title>
        存储页面
    </title>

</head>

<body>

    <script type="text/javascript">

        function SyncMessageServer(win, domain, onSendMessage) {
            window.addEventListener("message", function (ev) {
                var json = JSON.parse(ev.data);
                var fn = json.fn;
                ev.data = JSON.stringify(json);
                var result = onSendMessage(ev);
                ev.source.postMessage(
                    JSON.stringify({ fn: fn, args: [result] }), "*");

            });
        }
        function queryAnswserByQuestion(q) {

            return localStorage.getItem('Q:' + q);
        }

        function saveAnswser(q, a) {


            if (a && localStorage.getItem('Q:' + q) != a) {
                localStorage.setItem('Q:' + q, a);
                console.log('Q:' + q + '---> A:' + a);
            }

        }
        var sendMessageServer = new SyncMessageServer(window, "*", function (ev) {
            var json = JSON.parse(ev.data).data;
            if (json.cmd == "query") {
return queryAnswserByQuestion(json.q);
            }
            else if(json.cmd == "save"){
                return saveAnswser(json.q,json.a);
            }
          
        })
    </script>
</body>

</html>

  

posted @ 2018-04-07 17:52  阿牛  阅读(2384)  评论(0编辑  收藏  举报