【问题标题】:How to distinguish an iframe with the same origin from iframe with different origin如何区分具有相同来源的 iframe 和具有不同来源的 iframe
【发布时间】:2018-03-07 18:30:07
【问题描述】:

我的网页上有 2 个 iframe。 iframe S与网页同源,iframe D不同:

<iframe src="https://mdn-samples.mozilla.org/snippets/html/iframe-simple-contents.html" title="iframe example 1" width="400" height="300">
  <p>Your browser does not support iframes.</p>
</iframe>

我只需要将事件监听器添加到具有相同来源的 iframe 上。我就是这样做的:

for (let i = 0; i < frames.length; i++) {
    const iframe = window.frames[I]
    console.log(iframe)        
    if (iframe.document.domain === window.document.domain) {
        iframe.addEventListener('message', event => {
            console.log(event.data)
        }, false)
    }
}

但是,当我尝试读取 iframe D 的 iframe.document 时,会出现错误。

Uncaught DOMException: Blocked a frame with origin "http://localhost:8080" from accessing a cross-origin frame.

因为,与 iframe S 不同,当我从 2 sn 尝试 console.log(iframe) 时,iframe D 给了我这个对象上面代码的-p:

如您所见,没有文档属性。

【问题讨论】:

标签: javascript html dom iframe


【解决方案1】:

只需使用querySelectorAll 选择所有iframes,然后使用它们的src 属性构造一个新的URL,并检查它是否与您自己的hostname 匹配。

document.querySelectorAll('iframe').forEach(frame => {
  const url = new URL(frame.src)

  if (url.hostname === window.location.hostname) {
    frame.addEventListener('message', event => {
        console.log(event.data)
    }, false)
  }
})
<iframe src="https://stackoverflow.com"></iframe>
<iframe src="https://stackoverflow.com"></iframe>
<iframe src="https://stackoverflow.com"></iframe>
<iframe src="https://stackoverflow.com"></iframe>
<iframe src="https://stackoverflow.com"></iframe>
<iframe src="https://google.com"></iframe>

请注意,new URL 在 IE 浏览器中不起作用。您必须手动拆分您的 URL 部分以执行 hostname 相等性检查。

【讨论】:

    【解决方案2】:

    try - catch 块 包装整个 if 语句可以消除错误,但不确定这是否是解决此问题的最佳方法。

    for (let i = 0; i < frames.length; i++) {
        const iframe = window.frames[I]
        console.log(iframe)
        try {        
            if (iframe.document.domain === window.document.domain) {
                iframe.addEventListener('message', event => {
                    console.log(event.data)
                }, false)
            }
        }
        catch(error) {
        }
    }
    

    【讨论】:

    • 为什么不用if 而不是try.. catch
    • 你将如何构建它?我尝试了 if (iframe.document) 和 if (iframe)。第一个很荒谬,因为访问 .document 会导致错误,第二个不会将 iframe D 重新路由到 else 块。
    • 也许检查iframesrc 属性?
    • @NicholasKyriakides 同样的问题。我不认为我们被允许访问 iframe D 的任何属性。
    • 这没有意义。 iframeyour DOM 的一部分。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-14
    • 2021-09-15
    • 1970-01-01
    • 2020-08-26
    相关资源
    最近更新 更多