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>
QQ:273352165
evlon#126.com
转载请注明出处。