iframe - 带有 iframe "blocked a frame with origin from accessing a cross-origin frame"的 Chrome 扩展内容脚本

标签 iframe google-chrome-extension content-script

我已经浏览了一些关于 SO 的相关问题和解决方案,但似乎没有一个有最新的解决方案或与我类似的问题。

所以这是基本问题。我有一个在 https://example.com/* 上运行的内容脚本与更改 HTML5 <video> 的目标相匹配页面上的播放器。然而,实际的播放器在 iframe 中。为了获得实际的 HTMLMediaElement,我应该能够运行
document.querySelector("iframe").contentWindow.document.querySelector("video")
但是,这失败并出现错误
Uncaught DOMException: Blocked a frame with origin "https://example.com" from accessing a cross-origin frame.
更多信息document.querySelector("iframe").src返回 https://static.example.com/.../player.html . “来源”不同,但与原始站点的根域相同。

所以我想知道如何使用内容脚本(或者,我猜,任何其他方法)来操作 iframe 中的媒体播放器。

这是扩展的大致样子。
manifest.json

{
    "manifest_version": 2,
    //...
    "permissions": ["activeTab", "storage", "https://example.com/*"],
    //...
    "content_scripts": [
        {
            "all_frames": true,
            "matches": [
                "https://example.com/*"
            ],
            "js": [
                "inject.js"
            ]
        }
    ],
    //...
}
inject.js
winndow.onload = () => {
    document
        .querySelector("iframe.video-player")
        .contentWindow.document
        .querySelector("video#player_html5_api");
};

更新:

我不太确定为什么我之前没有想到这一点,但正如答案中提到的,将其视为完全不同的内容注入(inject)的关键。假设您不需要跨 iframe 边界的任何交互(仍然可以通过消息传递来实现),您只需修改 list 如下。关键是匹配 iframe 的来源,而不是页面的来源。 "all frames: true 行是必不可少的,因为默认情况下不会匹配不是最顶层的帧。
manifest.json
{
    //...
    "content_scripts": [
        {
            "all_frames": true,
            "matches": [
                "https://static.example.com/.../player.html"
            ],
            "js": [
                "inject.js"
            ]
        }
    ],
    //...
}

最佳答案

这里的重要内容来自这句话:

For additional information document.querySelector("iframe").src returns https://static.example.com/.../player.html. The "origin" is different, but is the same root-domain of the original site.



起源不同。 ( static.example.com != example.com ) 即使根域相同,但起源却不同。 (这就是为什么 tuckerchapin.sketchyfreewebhost.com 无法提供和修改来自 j6m8.sketchyfreewebhost.com 的内容)。因此,从理论上讲,这是“更好”的行为。

取自 this answer :

Protocol, hostname and port must be the same of your domain, if you want to access a frame.



(强调我的)

关于iframe - 带有 iframe "blocked a frame with origin from accessing a cross-origin frame"的 Chrome 扩展内容脚本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53566431/

相关文章:

dom - 如何读取加载了来自另一个域的页面的 iframe 的 DOM?

css - iframe url 到 css div url

javascript - 如何在 chrome 扩展中匹配 youtube 的 url?

google-chrome - Chrome 离屏标签捕获 API 和扩展程序白名单

javascript - Chrome 扩展代码 vs 内容脚本 vs 注入(inject)脚本

google-chrome-extension - 升级或安装后 Chrome 扩展程序内容脚本重新注入(inject)

php - 来自angularjs的iframe src不起作用

javascript - 创建 iframe 然后修改其内容

google-chrome - chrome 扩展 OnMessage

javascript - 在 Manifest V2 下的 Google Chrome 扩展中使用 YouTube 的 PlayerAPI - 有效,但会产生大量警告