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

Paw*_*lov 2 javascript iframe webkit frame cross-domain

这是特定于WebKit的浏览器(意味着我只需要使它在WebKit特定的工作,即iOS/Android浏览器,但我在Chrome中测试).

我有一个页面.该页面加载一个或多个iframe,其中包含来自另一个域的内容.我需要从这些iframe接收消息(使用postMessage()),我需要能够识别特定消息来自哪个iframe.

我无法找到一种方法来做那些不涉及投掷iframe内容然后可以传递给我的iframe URL.我不想干涉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);
Run Code Online (Sandbox Code Playgroud)

当帧加载时,它将运行:

window.parent.postMessage('do you know who I am?', '*');
Run Code Online (Sandbox Code Playgroud)

但是,frameElement在上面的onMessage()中未定义.我想出于安全原因,当父/子来自同一个域时,它确实可以正常工作.

它实际上具有讽刺意味.父窗口无法访问event.source.frameElement,因为event.source是一个外来窗口.iFrame窗口无法调用window.frameElement,因为frameElement位于外来窗口中.所以没有人可以访问它.

那么,有什么东西我可以用作我可以在新加载的框架上设置的标记,并以某种方式回来?

谢谢.

小智 7

对于寻找一些代码的人来说,以下是我用来查找发送消息的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;
}
Run Code Online (Sandbox Code Playgroud)

感谢Pawel Veselov和DMoses!