postMessage和iframe的使用

客户端与服务器传值还有几个经常会遇到的问题

1.页面和其打开的新窗口的数据传递
2.多窗口之间消息传递
3.页面与嵌套的iframe消息传递
4.上面三个问题的跨域数据传递

1.postMessage()

这些问题都有一些解决办法,但html5引入的message的API可以更方便、有效、安全的解决这些难题。postMessage()方法允许来自不同源的脚本采用异步方式进行有限的通信,可以实现跨文本档、多窗口、跨域消息传递。

postMessage(data,origin)方法接受两个参数

1.data:要传递的数据,html5规范中提到该参数可以是JavaScript的任意基本类型或可复制的对象,然而并不是所有浏览器都做到了这点儿,部分浏览器只能处理字符串参数,所以我们在传递参数的时候需要使用JSON.stringify()方法对对象参数序列化,在低版本IE中引用json2.js可以实现类似效果。
2.origin:字符串参数,指明目标窗口的源,协议+主机+端口号[+URL],URL会被忽略,所以可以不写,这个参数是为了安全考虑,postMessage()方法只会将message传递给指定窗口,当然如果愿意也可以建参数设置为”*”,这样可以传递给任意窗口,如果要指定和当前窗口同源的话设置为”/”。

2.iframe

两个基本概念:

主页面指的是嵌套iframe的页面
子页面指的是被嵌套的iframe页面

2.1 在主页面,想要操作子页面的DOM元素

contentWindow 兼容各个浏览器,可取得子窗口的 window 对象。
contentDocument Firefox 支持,> ie8 的ie支持,可取得子窗口的 document 对象。

var ifr = document.getElementById("iframe");    // 先获取iframe对象,此时的window是主页面的window对象
ifr.contentWindow.document.getElementById("div1")    //获取子页面iframe的window对象,此时ifr.contentWindow返回的是iframe的window对象,后面可以继续调用document方法
<iframe src="test.html" id=""></iframe> // 获取要操作的子页面的DOM元素
2.2 兼容获取document对象:
var getIFrameDoc = function(){
    var ifr = document.createElement("iframe");
    document.getElementsByTagName("body")[0].appendChild(ifr);
    return ifr.contentDocument || ifr.contentWindow.document;
}
2.3 在子页面,要操作主页面的DOM元素

window.parent 在iframe页面通过parent可以获得主页面的window,接着就可以正常访问父亲页面的元素了;
window.top() 这里的top是获取顶层的window,当有多层iframe嵌套的时候使用

var ifr = document.getElementByTagName("iframe");
ifr.parent.document.getElementById("div1")
<iframe src="test.html" id=""></iframe>

3.一些基本使用:

1,document.getElementById("myiframe").contentWindow 得到iframe对象后,就可以通过contentWindow得到iframe包含页面的window对象,然后就可以正常访问页面元素了;
2, $("#myiframe")[0].contentWindow jquery选择器获得iframe,先把jquery对象转换为DOM对象,或者使用get()方法转换;
3,$("#myiframe")[0].contentWindow.$("#div1").val()可以在得到iframe的window对象后接着使用jquery选择器进行页面操作;
4,$("#myiframe")[0].contentWindow.username="starry";可以通过这种方式向iframe页面传递参数,在iframe页面window.username就可以获取到值,username是自定义的全局变量;
5,在iframe页面通过parent可以获得主页面的window,接着就可以正常访问父亲页面的元素了;
6,parent.$("#frameA")[0].contentWindow.document.getElmentById("#frameB"); 同级iframe页面之间调用,需要先得到父亲的window,然后调用同级的iframe得到window进行操作;

    原文作者:StarryLake
    原文地址: https://www.jianshu.com/p/fd138d44fda5
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞