阅读HTML5高程,记录有关跨文档消息通信的范例:
环境配置:Apache/2.2.22 (Win32) PHP/5.4.0 Server at localhost Port 80
虚拟主机配置:
#测试跨域通信 <VirtualHost 127.0.0.60> DocumentRoot ../htdocs/HTM5Book/communication/visualhost/60 ServerName default:80 ErrorLog logs/phpMyAdmin-error_log </VirtualHost> <VirtualHost 127.0.0.70> DocumentRoot ../htdocs/HTM5Book/communication/visualhost/70 ServerName default:80 ErrorLog logs/phpMyAdmin-error_log </VirtualHost>
用两个文件夹模拟两个域下的html文件:
60中存放主页面文件,70中存放iframe中的页面
为了更加形象,配置了hosts文件:
127.0.0.60 portal.example.com
127.0.0.70 chat.example.net
那么现在在浏览器中测试了:http://portal.example.com/postMessagePortal.html
页面见下:
同时,通过子页面也可以向父页面发送消息。
相关代码:
父页面:
<!DOCTYPE html> <title>Portal [http://portal.example.com]</title> <link rel="stylesheet" href="styles.css"> <link rel="icon" href="http://apress.com/favicon.ico"> <script> var targetOrigin = "http://chat.example.net"; var defaultTitle = "Portal [http://portal.example.com]"; var notificationTimer = null; function messageHandler(e) { if (e.origin == targetOrigin) { notify(e.data); } else { // ignore messages from other origins } } function sendString(s) { document.getElementById("widget").contentWindow.postMessage(s, targetOrigin); } function notify(message) { stopBlinking(); blinkTitle(message, defaultTitle); } function stopBlinking() { if (notificationTimer !== null) { clearTimeout(notificationTimer); } document.title = defaultTitle; } function blinkTitle(m1, m2) { document.title = m1; notificationTimer = setTimeout(blinkTitle, 1000, m2, m1) } function sendStatus() { var statusText = document.getElementById("statusText").value; sendString(statusText); } function loadDemo() { document.getElementById("sendButton").addEventListener("click", sendStatus, true); document.getElementById("stopButton").addEventListener("click", stopBlinking, true); sendStatus(); } window.addEventListener("load", loadDemo, true); window.addEventListener("message", messageHandler, true); </script> <h1>Cross-Origin Portal</h1> <p><b>Origin</b>: http://portal.example.com</p> Status <input type="text" id="statusText" value="Online"> <button id="sendButton">Change Status</button> <p> This uses postMessage to send a status update to the widget iframe contained in the portal page. </p> <iframe id="widget" src="http://chat.example.net/postMessageWidget.html"></iframe> <p> <button id="stopButton">Stop Blinking Title</button> </p>
子页面:
<!DOCTYPE html> <title>widget</title> <link rel="stylesheet" href="styles.css"> <script> var targetOrigin = "http://portal.example.com"; // TODO whitelist array function messageHandler(e) { console.log(e); if (e.origin === "http://portal.example.com") { document.getElementById("status").textContent = e.data; } else { // ignore messages from other origins } } function sendString(s) { window.top.postMessage(s, targetOrigin); } function loadDemo() { document.getElementById("actionButton").addEventListener("click", function() { var messageText = document.getElementById("messageText").value; sendString(messageText); }, true); } window.addEventListener("load", loadDemo, true); window.addEventListener("message", messageHandler, true); </script> <h1>Widget iframe</h1> <p><b>Origin</b>: http://chat.example.net</p> <p>Status set to: <strong id="status"></strong> by containing portal.<p> <div> <input type="text" id="messageText" value="Widget notification."> <button id="actionButton">Send Notification</button> </div> <p> This will ask the portal to notify the user. The portal does this by flashing the title. If the message comes from an origin other than http://chat.example.net, the portal page will ignore it. </p>