在开发的过程中,需要实现对window.open父子窗口进行数据传递的功能,遇到了一些问题。
1.window.open函数
window.open("url","窗口名称","参数字符串")
参数窗口名可以是:_blank,_top,_self等
参数字符串是对生成的窗口属性的设置:如width、height、menubar、scrollbars等,以逗号隔开,如(height=250, width=600,menubar=no, scrollbars=no)
2.简单的参数传递
对于一般的参数传递,我们可以把参数添加到url中,通过get的方式实现参数传递。这种方式对于一般的参数对被访问者可见。参数较小的情况下可行。
3.遇到的问题
在开发中,已经有一些参数通过添加到url的方式传递到子窗口了,但现在需要传递其他一些数据,并且这些数据可能较大,用url的方式可能被截断。(注:需要传递的数据从后台用ajax获取)
4.尝试
4.1 考虑将ajax获取的数据先存放在本地文件,当子页面打开后利用js进行对文件数据的读取。由于js是运行在浏览器上,而不是操作系统上,实际可操作性小。
4.2 考虑利用浏览器对ajax数据进行存储,子页面从浏览器中取数据。尝试利用sessionStorage和localStorage进行数据存储,发现数据在父窗口可存可取,但在子窗口取不出(原因:子窗口打开是一个新的window对象,而sessionStorage和localStorage对象是window的属性对象)
4.3 利用html5的sendMessage函数进行数据传递。实际结果:可行。
5.利用sendMessage函数传递
父窗口打开子窗口:
var popupwin = window.open('configfunc.html?ft=' + encodeURI(ft) + '&name=' + me_name + '&version=' + version + '&fields=' + other_fields,
"配置函数", "height=250, width=600, top=50, left=150, toolbar=no, menubar=no, scrollbars=no, resizable=no,location=no, status=no");
popupwin.onload = function(e) {
popupwin.postMessage(functionInfos,"chrome-extension://"+window.location.host);
}
子窗口接受数据:
document.onreadystatechange = function(e){
if(document.readyState == 'complete') {
window.addEventListener('message', function(e){
var data = e.data;
fucNames = data;
console.log("get data from father");
console.log(fucNames);
if(fucNames instanceof Array) {
for (var i in fucNames) {
console.log(fucNames[i]);
var option = document.createElement('option');
option.value = fucNames[i]['funcTemplate'];
option.innerHTML = fucNames[i]['funcName'] + '---' + fucNames[i]['version'];
selectBox.appendChild(option);
}
}
else {
console.log(fucNames);
}
});
}
}
postMessage()函数实际上是通过listener监听器实现的。在postMessage函数的参数中,第一个参数是要传递的数据,第二个参数是目标页面的地址。postMessage函数通过第
二个参数获得目标页面的句柄,再将数据传递到目标页面的消息队列中,实现数据异步传输。
注意:postMessage()函数的第二个参数必须要与目标参数的url对应,包括协议。上例中是在chrome插件中打开子窗口,故协议是chrome-extension://