除了应尽可能避免的一般规则eval
外,您当前的代码并不安全。
跨文档消息传递应该是跨域通信的安全技术。这里最重要的方面是尊重来源:发送者可以决定消息可以发送到哪个来源的文档,而接收者可以决定它可以接受来自哪个来源的消息。
但在您的情况下,您的发件人既没有指定收件人来源,也没有收件人检查发件人来源。这是一个安全漏洞,因为您的发件人可以将消息发送给错误的收件人(您的框架的文档更改),或者您的收件人接受来自错误发件人的带有潜在恶意代码的消息(您的文档嵌入在恶意页面中)。
因此,为了使您的跨文档消息传递安全,请始终在postMessage
调用中指定发件人的来源:
otherWindow.postMessage(message, "http://example.org:8080");
并在收到消息时始终检查来源:
function receiveMessage(event) {
if (event.origin !== "http://example.org:8080") return;
// ...
}
window.addEventListener("message", receiveMessage, false);
如果您在同一来源内进行通信,则可以使用window.location.origin
:
// sender
otherWindow.postMessage(message, window.location.origin);
// recipient
if (event.origin !== window.location.origin) return;
window.location.origin
似乎仅在 WebKit 中可用,这里有一个解决方法:
if (!window.location.hasOwnProperty("origin")) {
window.location.origin = window.location.protocol + "//" + window.location.host;
}