这是特定于WebKit的浏览器(这意味着我只需要使其在特定于WebKit的工具(即iOS / Android浏览器)中运行,但是我正在Chrome中进行测试)。
我有一页该页面会加载一个或多个iframe,以及来自另一个域的内容。我需要从这些iframe接收消息(使用postMessage()),并且需要能够确定特定消息来自哪个iframe。
我找不到一种不涉及抛出iframe URL的方法,而iframe内容随后可以传递给我。我不想混入URL,因为不能保证我可以安全地做到这一点(例如,重定向可以将参数丢弃)。
我尝试了一些我认为合理的事情。当我创建iframe元素时(通过J / S完成),我将一个属性与该元素相关联,假设为“shared_secret”。当我从框架返回消息事件时,我试图找到创建调用框架的元素,并读取该属性。
function onMessage(evt) {
var callerId = evt.source.frameElement.shared_secret;
// ....
}
window.addEventListener(message, onMessage);
var frameEl = document.createElement('iframe');
frameEl.shared_secret = 'sommething blue';
frameEl.src = 'http://aliens.com/my.html';
somewhereInMyDoc.appendChild(frameEl);
框架加载后,它将运行:
window.parent.postMessage('do you know who I am?', '*');
但是,在上面的onMessage()中,frameElement的结果不确定。我猜出于安全原因,当父/子来自同一个域时,它确实可以正常工作。
实际上,这具有讽刺意味。父窗口无法访问event.source.frameElement,因为event.source是一个外来窗口。 iframe窗口无法调用window.frameElement,因为frameElement在外部窗口中。因此,没有人可以访问它。
因此,有什么我可以用作 token 的东西,可以在新加载的帧上设置它,并且以某种方式返回吗?
谢谢。
最佳答案
对于寻找某些代码的人,这是我用来查找发送消息的iframe的内容:
/**
* Returns the iframe corresponding to a message event or null if not found.
*
* 'e' is the event object
*/
function getFrameTarget (e) {
var frames = document.getElementsByTagName('iframe'),
frameId = 0,
framesLength = frames.length;
for (; frameId < framesLength; frameId++) {
if (frames[frameId].contentWindow === e.source) {
return frames[frameId];
}
}
return null;
}
感谢Pawel Veselov和DMoses!
关于javascript - 如何在JavaScript中的窗口和框架之间共享数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8500276/