Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/381.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在JavaScript中在窗口和框架之间共享数据_Javascript_Iframe_Webkit_Cross Domain_Frame - Fatal编程技术网

如何在JavaScript中在窗口和框架之间共享数据

如何在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,因为不能保证我可以安全地这样做(例如,重定向可以抛出参数) 我

这是特定于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?', '*');
但是,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进行比较?