我从父窗口启动一个新的浏览器窗口:
window.open(url, "MyAppTitle", "width=300, height=600, menubar=no, scrollbars=no, resizable=no");
子窗口需要密码才能连接到服务。要将密码从父母发送给孩子,我使用:
window.passwdString = "mypassword";
其中
mypassword
是需要传输到另一个窗口的密码。
然后,在另一个窗口中,我使用以下命令检索密码:
var userPass = window.opener.passwdString;
在桌面浏览器中一切正常,但在移动浏览器中则不起作用。为了使其在移动浏览器中工作,我可以将密码保存到 localStorage 或 sessionStorage:
localStorage.setItem("passwdString", "mypassword");
然后通过以下方式获取值:
var userPass = localStorage.getItem("passwdString");
这种方法的问题是安全性较低。即使我在使用密码建立连接后立即删除密码(使用
localStorage.remove("passwdString")
),仍然有几秒钟的时间将其保存到浏览器的存储中。
我还尝试了其他建议,例如:
var newWindow = window.open(url, "MyAppTitle", "width=300, height=600, menubar=no, scrollbars=no, resizable=no");
newWindow.passwdString = "mypassword";
然后,在新窗口中,使用以下命令检索它:
window.passwdString
或
var newWindow = window.open(url, "MyAppTitle", "width=300, height=600, menubar=no, scrollbars=no, resizable=no");
newWindow["passwdString"] = "mypassword";
然后,在新窗口中,使用以下命令检索它:
window["passwdString"]
但它们不适用于移动浏览器。唯一有效的方法是使用 localStorage 或 sessionStorage 来存储密码,然后在使用它建立连接后将其删除。然而,这似乎不太安全。我知道使用第一种方法传递数据也不是很安全,但在这种情况下,它不会保存到浏览器的存储中。将数据作为添加到 URL 的查询参数传递也是不安全的。我的问题是:将敏感字符串从父窗口传递到子窗口的最佳方法是什么,以便它在桌面和移动浏览器中工作? 谢谢你。
感谢“Mike 'Pomax' Kamermans”的留言。事实上,这个问题的通用解决方案是使用 postMessage() 方法:
在父窗口添加:
var windpop = window.open(url, "MyAppTitle", "width=300, height=600, menubar=no, scrollbars=no, resizable=no");
windpop.postMessage("mypassword", window.location.origin);
然后,在子窗口上添加:
window.addEventListener("message", function(event) {
if (event.origin == window.location.origin) {
var userPass = event.data;
/* use userPass to connect to web service, etc. */
}
}, false);
就我而言,两个窗口都位于同一域中。这就是为什么在获取密码之前,我验证了弹出窗口的 URL 基址 (window.location.origin) 是否与打开弹出窗口的窗口 (event.origin) 相同。
但是,现在许多用户都将浏览器配置为阻止弹出窗口。当浏览器阻止弹出窗口时,上面的
windpop
变量为 null,即使新窗口完全加载后它仍然为 null。因此,永远不会触发 windpop.postMessage()
,并且子窗口不会从父窗口获取任何数据。