如何在JavaScript中在窗口和框架之间共享数据
这是特定于WebKit浏览器的(这意味着我只需要让它在特定于WebKit的浏览器中工作,即iOS/Android浏览器,但我正在Chrome中进行测试) 我有一页。页面加载一个或多个iFrame,其中包含来自另一个域的内容。我需要从这些iframe接收消息(使用postMessage()),并且我需要能够识别特定消息来自哪个iframe 我找不到一种不涉及抛出iframe URL的方法,iframe内容可以传递回我。我不想干预URL,因为不能保证我可以安全地这样做(例如,重定向可以抛出参数) 我尝试了一些我认为合理的东西。当我创建iframe元素(它是从J/s完成的)时,我将一个属性与该元素相关联,比如“shared_secret”。当我从框架中获取消息事件时,我尝试定位调用框架所使用的元素,并读取该属性如何在JavaScript中在窗口和框架之间共享数据,javascript,iframe,webkit,cross-domain,frame,Javascript,Iframe,Webkit,Cross Domain,Frame,这是特定于WebKit浏览器的(这意味着我只需要让它在特定于WebKit的浏览器中工作,即iOS/Android浏览器,但我正在Chrome中进行测试) 我有一页。页面加载一个或多个iFrame,其中包含来自另一个域的内容。我需要从这些iframe接收消息(使用postMessage()),并且我需要能够识别特定消息来自哪个iframe 我找不到一种不涉及抛出iframe URL的方法,iframe内容可以传递回我。我不想干预URL,因为不能保证我可以安全地这样做(例如,重定向可以抛出参数) 我
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?', '*');
但是,frameElement在上面的onMessage()中没有定义。我想出于安全考虑,当父/子节点来自同一个域时,它确实可以完美地工作
这其实很讽刺。父窗口无法访问event.source.frameElement,因为event.source是外来窗口。iFrame窗口无法调用window.frameElement,因为frameElement位于外来窗口中。所以没人能得到它
那么,有没有什么东西可以用作标记,我可以在新加载的帧上设置,然后以某种方式返回
谢谢。这应该归功于 实际上,您可以将frame元素的content窗口对象与消息事件的event.source进行比较,如果它们实际上相同,则比较结果将为TRUE 因此,为了解决我的特殊问题,我需要保留我创建的框架元素列表(如果需要,使用任何附加属性对它们进行喷洒),并且在事件发生时,遍历所有元素,查找其contentWindow属性等于event.source属性的元素
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);
更新
通过遇到一些讨厌的bug,我们也发现应该在父窗口中创建的iframe上添加一个“id”。尤其是当窗口本身在iframe中时。否则,即使消息是从完全不同的子帧接收到的,某些(Android 4.x肯定是已知的)浏览器也会产生真正的比较。对于寻找某些代码的人,以下是我用来查找发送消息的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;
}
/**
*返回与消息事件对应的iframe,如果未找到,则返回null。
*
*“e”是事件对象
*/
函数getFrameTarget(e){
var frames=document.getElementsByTagName('iframe'),
frameId=0,
framesLength=frames.length;
对于(;frameId
多亏了Pawel Veselov和DMOS 您是试图从子iframe访问父窗口还是通过其他方式访问父窗口?我不是试图从彼此访问窗口,真的。我使用消息API,但我需要知道我的哪个孩子在打电话。而且无法事先就标识字符串达成一致。event.origin字段是否具有所需的值?:)非常感谢。而且,顺便说一句,origin不能处理散列。来源仅返回域。对于“{123,.42}”,event.origin是“”。我让帧传递给我它在发送的消息中是散列的,这是我发现的唯一解决方案(由于服务器的不确定性,仍然不够)您不能循环通过window.frames内容窗口并将其与evt.source进行比较?