zoukankan      html  css  js  c++  java
  • postMessage

     f.contentWindow.postMessage("SB","http://localhost");

    <button id="send">Send Message</button>
    <iframe id="receiver" src="http://demos.matt-west.com/post-message/receiver.html" width="400" height="200">

    <p>Your browser does not support iframes.</p>
    </iframe>

    window.onload = function() {
    // Get the window displayed in the iframe.
    var receiver = document.getElementById('receiver').contentWindow;

    // Get a reference to the 'Send Message' button.
    var btn = document.getElementById('send');

    // A function to handle sending messages.
    function sendMessage(e) {
    // Prevent any default browser behaviour.
    e.preventDefault();

    // Send a message with the text 'Hello Treehouse!' to the receiver window.
    receiver.postMessage('Hello Treehouse!', 'http://demos.matt-west.com');
    }

    // Add an event listener that will execute the sendMessage() function
    // when the send button is clicked.
    btn.addEventListener('click', sendMessage);
    }

    <div id="message"></div>

    <script src="receiver.js"></script>

    window.onload = function() {
    // Get a reference to the <div> on the page that will display the
    // message text.
    var messageEle = document.getElementById('message');

    // A function to process messages received by the window.
    function receiveMessage(e) {
    // Check to make sure that this message came from the correct domain.
    if (e.origin !== "http://s.codepen.io")
    return;

    // Update the div element to display the message.
    messageEle.innerHTML = "Message Received: " + e.data;
    }

    // Setup an event listener that calls receiveMessage() when the window
    // receives a new MessageEvent.
    window.addEventListener('message', receiveMessage);
    }

    同域限制和window.postMessage方法

    来自《JavaScript 标准参考教程(alpha)》,by 阮一峰

    目录

    概述

    所谓“同域限制”指的是,出于安全考虑,浏览器只允许脚本与同样协议、同样端口、同样域名的地址进行通信。比如,www1.example.com页面上面的脚本,只能与该域名(相同协议、相同端口)进行通信,如果与www2.example.com通信,浏览器就会报错(不过可以设置两者的document.domain为相同的值)。这是为了防止恶意脚本将用户信息发往第三方网站。

    window.postMessage方法就是用来在某种程度上,绕过同域限制,实现不同域名的窗口(包括iframe窗口)之间的通信。它的格式如下。

    targetWindow.postMessage(message, targetURL[, transferObject]);

    上面代码的targetWindow是指向目标窗口的变量,message是要发送的信息,targetURL是指定目标窗口的网址,不符合该网址就不发送信息,transferObject则是跟随信息一起发送的Transferable对象。

    下面是一个postMessage方法的实例。假定当前网页弹出一个新窗口。

    var popup = window.open(...popup details...);
    
    popup.postMessage("Hello World!", "http://example.org");

    上面代码的postMessage方法的第一个参数是实际发送的信息,第二个参数是指定发送对象的域名必须是example.org。如果对方窗口不是这个域名,信息不会发送出去。

    然后,在当前网页上监听message事件。

    window.addEventListener("message", receiveMessage, false);
    
    function receiveMessage(event) {
    	if (event.origin !== "http://example.org")
        return;
    
    	if (event.data == 'Hello World') {
          event.source.postMessage('Hello', event.origin);
        } else {
          console.log(event.data);
        }
    
    }

    上面代码指定message事件的回调函数为receiveMessage,一旦收到其他窗口发来的信息,receiveMessage函数就会被调用。receiveMessage函数接受一个event事件对象作为参数,该对象的origin属性表示信息的来源网址,如果该网址不符合要求,就立刻返回,不再进行下一步处理。event.data属性则包含了实际发送过来的信息,event.source属性,指向当前网页发送信息的窗口对象。

    最后,在popup窗口中部署下面的代码。

    
    // popup窗口
    
    function receiveMessage(event) {
      event.source.postMessage("Nice to see you!", "*");
    }
    
    window.addEventListener("message", receiveMessage, false);
    
    

    上面代码有几个地方需要注意。首先,receiveMessage函数里面没有过滤信息的来源,任意网址发来的信息都会被处理。其次,postMessage方法中指定的目标窗口的网址是一个星号,表示该信息可以向任意网址发送。通常来说,这两种做法是不推荐的,因为不够安全,可能会被恶意利用。

    所有浏览器都支持这个方法,但是IE 8和IE 9只允许postMessage方法与iFrame窗口通信,不能与新窗口通信。IE 10允许与新窗口通信,但是只能使用IE特有的MessageChannel对象

    iframe与主页面的通信

    iframe中的网页,如果与主页面来自同一个域,通过设置document.domain属性,可以使用postMessage方法实现双向通信。

    下面是一个LocalStorage的例子。LocalStorage只能用同一个域名的网页读写,但是如果iframe是主页面的子域名,主页面就可以通过postMessage方法,读写iframe网页设置的LocalStorage数据。

    iframe页面的代码如下。

    
    document.domain = "domain.com";
    window.onmessage = function(e) {
      if (e.origin !== "http://domain.com") {
        return;
      }
      var payload = JSON.parse(e.data);
      localStorage.setItem(payload.key, JSON.stringify(payload.data));
    };
    
    

    主页面的代码如下。

    
    window.onload = function() {
        var win = document.getElementsByTagName('iframe')[0].contentWindow;
        var obj = {
           name: "Jack"
        };
        win.postMessage(JSON.stringify({key: 'storage', data: obj}), "*");
    };
    
    

    上面的代码已经可以实现,主页面向iframe传入数据。如果还想读取或删除数据,可以进一步加强代码。

    加强版的iframe代码如下。

    
    document.domain = "domain.com";
    window.onmessage = function(e) {
        if (e.origin !== "http://domain.com") {
            return;
        }
        var payload = JSON.parse(e.data);
        switch(payload.method) {
            case 'set':
                localStorage.setItem(payload.key, JSON.stringify(payload.data));
                break;
            case 'get':
                var parent = window.parent;
                var data = localStorage.getItem(payload.key);
                parent.postMessage(data, "*");
                break;
            case 'remove':
                localStorage.removeItem(payload.key);
                break;
        }
    };
    
    

    加强版的主页面代码如下。

    
    window.onload = function() {
        var win = document.getElementsByTagName('iframe')[0].contentWindow;
        var obj = {
           name: "Jack"
        };
        // 存入对象
        win.postMessage(JSON.stringify({key: 'storage', method: "set", data: obj}), "*");
        // 读取以前存取的对象
        win.postMessage(JSON.stringify({key: 'storage', method: "get"}), "*");
        window.onmessage = function(e) {
            if (e.origin != "http://sub.domain.com") {
                return;
            }
            // 下面会输出"Jack"
            console.log(JSON.parse(e.data).name);
        };
    };
    

     

  • 相关阅读:
    nginx $remote_addr 详解
    Alipay SDK验签PHP低于5.5版本错误
    Alipay支付宝调用错误:Call to undefined function openssl_sign()
    nginx.conf 下日志host.access.log 说明
    vim全选,全部复制,全部删除
    jquery 获取上传文件大小
    linux网络配置
    crontab 定时任务简单备份数据库
    linux进程管理
    mysql 动态增加列,查找表中有多少列,具体什么列。 通过JSON生成mysql表 支持子JSON
  • 原文地址:https://www.cnblogs.com/jayruan/p/5353864.html
Copyright © 2011-2022 走看看