關(guān)于postMessage
window.postMessage雖然說是html5的功能,但是支持IE8+,假如你的網(wǎng)站不需要支持IE6和IE7,那么可以使用window.postMessage。關(guān)于window.postMessage,很多朋友說他可以支持跨域,不錯(cuò),window.postMessage是客戶端和客戶端直接的數(shù)據(jù)傳遞,既可以跨域傳遞,也可以同域傳遞。
應(yīng)用場景
我只是簡單的舉一個(gè)應(yīng)用場景,當(dāng)然,這個(gè)功能很多地方可以使用。
假如你有一個(gè)頁面,頁面中拿到部分用戶信息,點(diǎn)擊進(jìn)入另外一個(gè)頁面,另外的頁面默認(rèn)是取不到用戶信息的,你可以通過window.postMessage把部分用戶信息傳到這個(gè)頁面中。(當(dāng)然,你要考慮安全性等方面。)
代碼舉例
發(fā)送信息:
JavaScript Code復(fù)制內(nèi)容到剪貼板
-
- var domain = 'http://haorooms.com';
- var myPopup = window.open(domain
- + '/windowPostMessageListener.html','myWindow');
-
-
- setTimeout(function(){
-
- var message = {name:"站點(diǎn)",sex:"男"};
- console.log('傳遞的數(shù)據(jù)是 ' + message);
- myPopup.postMessage(message,domain);
- },1000);
要延遲一下,我們一般用計(jì)時(shí)器setTimeout延遲再發(fā)用。
接受的頁面
JavaScript Code復(fù)制內(nèi)容到剪貼板
-
- window.addEventListener('message',function(event) {
- if(event.origin !== 'http://haorooms.com') return; //這個(gè)判斷一下是不是我這個(gè)域名跳轉(zhuǎn)過來的
- console.log('received response: ',event.data);
- },false);
如下圖,接受頁面得到數(shù)據(jù)
![](/d/20211016/d9c36bf9b3a5da18f13e3d07f6b20de0.gif)
如果是使用iframe,代碼應(yīng)該這樣寫:
JavaScript Code復(fù)制內(nèi)容到剪貼板
-
- var domain = 'http://haorooms.com';
- var iframe = document.getElementById('myIFrame').contentWindow;
-
-
- setTimeout(function(){
-
- var message = {name:"站點(diǎn)",sex:"男"};
- console.log('傳遞的數(shù)據(jù)是: ' + message);
-
- iframe.postMessage(message,domain);
- },1000);
接受數(shù)據(jù)
JavaScript Code復(fù)制內(nèi)容到剪貼板
-
- window.addEventListener('message',function(event) {
- if(event.origin !== 'http://haorooms.com') return;
- console.log('message received: ' + event.data,event);
- event.source.postMessage('holla back youngin!',event.origin);
- },false);
上面的代碼片段是往消息源反饋信息,確認(rèn)消息已經(jīng)收到。下面是幾個(gè)比較重要的事件屬性:
source – 消息源,消息的發(fā)送窗口/iframe。
origin – 消息源的URI(可能包含協(xié)議、域名和端口),用來驗(yàn)證數(shù)據(jù)源。
data – 發(fā)送方發(fā)送給接收方的數(shù)據(jù)。
調(diào)用實(shí)例
1. 主線程中創(chuàng)建 Worker 實(shí)例,并監(jiān)聽 onmessage 事件
JavaScript Code復(fù)制內(nèi)容到剪貼板
- <html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
- <title>Test Web worker</title>
- <script type="text/JavaScript">
- function init(){
- var worker = new Worker('compute.js');
-
- worker.onmessage= function (event) {
-
- document.getElementById("result").innerHTML +=
- event.data+"<br/>";
- };
- }
- </script>
- </head>
- <body onload="init()">
- <div id="result"></div>
- </body>
- </html>
在客戶端的 compute.js 中,只是簡單的重復(fù)多次加和操作,最后通過 postMessage 方法把結(jié)果返回給主線程,目的就是等待一段時(shí)間。而在這段時(shí)間內(nèi),主線程不應(yīng)該被阻塞,用戶可以通過拖拽瀏覽器,變大縮小瀏覽器窗口等操作測試這一現(xiàn)象。這個(gè)非阻塞主線程的結(jié)果就是 Web Workers 想達(dá)到的目的。
2. compute.js 中調(diào)用 postMessage 方法返回計(jì)算結(jié)果
JavaScript Code復(fù)制內(nèi)容到剪貼板
- var i=0;
-
- function timedCount(){
- for(var j=0,sum=0;j<100;j++){
- for(var i=0;i<100000000;i++){
- sum+=i;
- }
- }
-
- postMessage(sum);
- }
-
- postMessage("Before computing,"+new Date());
- timedCount();
- postMessage("After computing,"+new Date());