访问DOM元素数据文件->Iframe->Iframe->方法chrome扩展

Access DOM elements data document->Iframe ->Iframe->method chrome extension

我正在尝试从开发人员控制台访问嵌套在 iframe 中的 iframe 中的一些数据:

Object.keys(document.getElementById("contentBody").
  contentDocument.getElementById('rawContent').
  contentDocument.defaultView.window.messages)

["29c736c0ed25463c8436f4990ab6c6ec.zip", 
 "235819a8cf11488e83f0336603b71711.zip", 
 "66c9260590834d9698568c8a676ef406.zip", 
 "fae95e31cb424cd6ad21302217ef2cdc.zip", 
 "f554f712141047aa9aa24f765073e305.zip", 
 "e5c41819578240e0868f43ab6301aeb3.zip"]

这就是我所期望的,但我试图从我正在开发的 google chrome 扩展中获取完全相同的信息,但由于某种原因我无法访问消息数组,这是清单文件和 contentscript.js(我已经尝试了我想到的所有方法并搜索了几个小时但没有成功:/):

content.js

var iframeContentBody = document.getElementById('contentBody');
var innerDocContentBody = iframeContentBody.contentDocument;
var iframeRawContent = innerDocContentBody.getElementById('rawContent');
var innerDocRawContent = iframeRawContent.contentDocument; // iframeRawContent is undefined here
console.log(iframeRawContent.messages);  // this prints undefined

清单:

{                                                                                                                                                                                                                  
  "manifest_version": 2,                                                                                                                                                                                           

  "name": "Read Comments",
  "description": "Read all comments from the current forum",
  "version": "1.0",
  "content_scripts": [{
    "matches": ["*://*.forum.net/*"],
    "js": ["content.js"]
  }],
 "browser_action": {
   "default_title": "Read Comments"
 },
 "permissions": ["activeTab", "tabs"]
} 

设置一切的要点:

HTML Example

下载这 3 个文件并将其放在同一个文件夹后,运行 这个:

python -m SimpleHTTPServer 80 # You may need to run it with sudo 

然后转到 localhost/test.html 一切就绪,如果您测试我在控制台中发布的行,您应该会看到 [1,2,3]

Extension example

这是扩展代码

开发者控制台:

Chrome 扩展 "all_frames": true

Hacky 解决方案:Partial solution 在这个要点中有一种方法可以做到这一点,很难检测到 iframe 何时加载,也很难检测到另一个 iframe 中的 iframe 何时加载,因此 setTimeout 提供了足够的时间来完成它,然后将脚本元素添加到 dom 似乎绕过了 chrome 扩展可能具有的所有安全措施,并且它确实获取了属性的内容而没有任何其他问题,但这看起来很老套,这不是我的意思我正在尝试这样做,我正在寻找一种干净的解决方案或一种干净的方法来访问嵌套 iframe 的 dom,如示例代码所述...

谢谢,欢迎任何建议。

毕竟这是我的解决方案,介于我们通过评论讨论的内容和我通过文档和其他线程进行的研究之间:

内容脚本:

(function () {
  document.addEventListener("DOMContentLoaded", function () {
    contentBody = document.getElementById("contentBody");
    contentBody.addEventListener("load", function () {
      rawContent = contentBody.contentDocument.getElementById("rawContent");
      if (rawContent) {
        var s = document.createElement("script");
        s.src = chrome.extension.getURL('injected.js');
        s.onload = function() {
          this.parentNode.removeChild(this);
        };

        (document.head||document.documentElement).appendChild(s);
      }
    });
  });
})();

注入的文件:

keys = Object.keys(document.getElementById("contentBody").contentDocument.getElementById("rawContent").contentDocument.defaultView.window.messages);

console.log(keys);

清单:

{
  "manifest_version": 2,

  "name": "Read Comments",
  "description": "Read all comments from the current forum",
  "version": "0.0.1",

  "content_scripts": [{
    "matches": ["*://localhost/*"],
    "run_at": "document_start",
    "js": ["content.js"]
  }],

  "browser_action": {
    "default_title": "Read Comments"
  },

  "permissions": [
  ],

  "web_accessible_resources": ["content.js", "injected.js"]
}

作为一个简单的解释,主要问题是 iframe 的异步加载和扩展代码 运行 的那一刻,所以在听了很多事件并丢弃那些没有要求的事件之后dom 上的元素一切顺利...

为了完整起见,这里有一个带有 "all_frames":true 的版本。有两个问题需要解决:(1)从内部框架到顶部获取 messages 和(2)从网页的孤立世界获取 messages 到内容脚本的孤立世界(我假设您想要做的不仅仅是将 messages 写入控制台)。这通过使用 postMessage.

同时解决了这两个问题
if ( window.top !== window.parent ) {
    var s = document.createElement("script");
    s.textContent = "postMessage(messages,'*');";
    s.onload = function() {
        this.parentNode.removeChild(this);
    };
    document.head.appendChild(s);
} else if ( window.top === window ) {
    addEventListener('message',function(e) {
        console.log(e.data);
    });
}

我必须承认我还没有实际测试过。您可能需要尝试制作注入脚本 send a message from the webpage.