【问题标题】:How to get DOM from debugging tab to extension script如何从调试选项卡获取 DOM 到扩展脚本
【发布时间】:2013-01-07 22:25:32
【问题描述】:

我在这里寻求一些帮助,因为我看到的示例只是从标签到扩展,而不是相反。

我正在寻找使用自定义 Chrome 扩展程序调试的页面/选项卡的源代码。我希望扩展程序调用一条消息并将响应发送回进行调用的扩展程序面板 javascript。

清单

"permissions": [
  "tabs",
  "<all_urls>",
  "debugger"
],
"background": {
  "scripts": ["background.js"],
  "persistent": false
},
"content_scripts": [
  {
  "matches": ["<all_urls>"],
  "js": ["content.js"]
  }
],

background.js

chrome.browserAction.onClicked.addListener(function() {
  chrome.tabs.query({active:true, windowId:chrome.windows.WINDOW_ID_CURRENT}, function(tabs) {
    debuggee = {tabId:tabs[0].id};
chrome.debugger.attach(debuggee, version, onAttach.bind(null, tabs[0].id));
  });
});

function onAttach(tabId) {
  chrome.windows.create({url: "spy.html?" + tabId, type: "panel", width: 900, height: 700}, function(window) {
    winId = window.id;
});

content.js

chrome.extension.onMessage.addListener(function(request, sender, sendResponse) {
  if (request.data == "getHTML") {
      sendResponse({data: document.getElementById('header').innerHTML});
  }
});

spy.html

<script src="spy.js" type="text/javascript"></script>

spy.js

window.addEventListener("load", function() {
  chrome.debugger.sendCommand({tabId:tabId}, "DOM.getDocument");
  chrome.debugger.onEvent.addListener(onEvent);
});

function onEvent(debuggeeId, message, params) {    
  if (message=="DOM.documentUpdated") {
    chrome.tabs.sendMessage(tabId, {data: "getHTML"}, function(response) {console.log(response.data);});
  }

结果

端口错误:无法建立连接。接收端不存在。 miscellaneous_bindings:235 chromeHidden.Port.dispatchOnDisconnect miscellaneous_bindings:235

“未定义”的事件处理程序出错:无法读取未定义的属性“数据”类型错误:无法读取未定义的属性“数据”
在 chrome-extension://fpdkndicjblnkakkiiapbbdflkehjmgm/headers.js:132:91
在 miscellaneous_bindings:279:11
在 chrome.Event.dispatchToListener (event_bindings:387:21)
在 chrome.Event.dispatch_ (event_bindings:373:27)
在 chrome.Event.dispatch (event_bindings:393:17)
在 Object.chromeHidden.Port.dispatchOnDisconnect (miscellaneous_bindings:238:27)

当我尝试运行它时出现此错误。我错过了什么?

【问题讨论】:

  • background.js 在哪里?
  • 我已经更新了最初的帖子。感谢收看。
  • @ilya: windows.getCurrenttabs.getSelected 已弃用,chrome.debugger.attach 只有两个参数
  • @Sudarshan 所以我应该重新设计流程以匹配您的答案。即删除清单中的“背景”并将popup.html添加到浏览器操作中?我在 background.js 中有其他代码,主要是侦听器。 1) chrome.windows.onRemoved -> 分离调试器 2) chrome.debugger.onDetach -> 删除弹出窗口
  • @Sudarshan 顺便说一句,您可以为附加指定回调 - developer.chrome.com/extensions/debugger.html#method-attach

标签: google-chrome-extension


【解决方案1】:

您如何捕获chrome.tabs.sendMessage(tabId, 中的tabId,如果您正在寻找将消息从Chrome Extension 传递到Debugging Tab 的示例代码,您能否发布您的完整脚本来调试问题,请检查此。

参考文献

manifest.json

注册popup页面和content scripts

{
 "name": "Pass message from Chrome Extension to Debugging Tab",
 "version": "1",
 "description": "http://stackoverflow.com/questions/14205155/how-can-i-pass-a-message-from-my-chrome-extension-to-debugging-tab",
 "browser_action": {
   "default_title": "Selected Text",
   "default_popup": "popup.html" 
 },
 "permissions": [
   "tabs",
   "<all_urls>"
 ],
 "content_scripts": [
  {
    "matches": ["<all_urls>"],
    "js": ["selection.js"]
  }
 ],
 "manifest_version": 2
}

popup.html

确保 HTML 遵守 CSP

<!DOCTYPE html>
<html>

    <head>
        <style>
            body {
                width: 300px;
            }
            textarea {
                width: 250px;
                height: 100px;
            }
        </style>
        <script src="popup.js"></script>
    </head>

    <body>
          <button id="submit">Pass Message</button>
    </body>

</html>

popup.js

将消息传递给内容脚本。

function passMessage() {
    //Select current tab to send message
  chrome.tabs.query({"active":true,"currentWindow":true,"status":"complete","windowType":"normal"}, function(tabs) {
  //It returns array so looping over tabs result
    for(tab in tabs){

    //Send Message to a tab
    chrome.tabs.sendMessage(tabs[tab].id, {method: "Hi Content Script"});
    }   
});
}


// Bind On click event to passMessage() function
document.addEventListener("DOMContentLoaded",function (){

    document.getElementById("submit").onclick = passMessage;
});

selection.js

添加了一个处理程序来捕获从弹出页面发送的消息

 //Add a handler to handle message sent from popup.html
 chrome.extension.onMessage.addListener(function(request, sender) {
    console.log("Message "+request+" is recieved");

});

编辑:

在消除了一些不推荐使用的 API() 之后,我让你的代码工作了,比如 sendResponse

background.js

chrome.browserAction.onClicked.addListener(function () {
    version = "1.0";
    chrome.tabs.query({
        active: true,
        windowId: chrome.windows.WINDOW_ID_CURRENT
    }, function (tabs) {
        debuggee = {
            tabId: tabs[0].id
        };
        chrome.debugger.attach(debuggee, version, onAttach.bind(null, tabs[0].id));
    });
});

function onAttach(tabId) {
    chrome.windows.create({
        url: "spy.html?" + tabId,
        type: "panel",
        width: 900,
        height: 700
    }, function (window) {
        winId = window.id;
    });
}

content.js

chrome.extension.onMessage.addListener(function (request, sender) {
    console.log("Message recieved");
    if (request.data == "getHTML") {
        chrome.extension.sendMessage({
            "data": "Some Stuff"
        });
    }
});

spy.js

tabId = parseInt(window.location.search.substring(1));
window.addEventListener("load", function () {

    chrome.debugger.sendCommand({
        tabId: tabId
    }, "DOM.getDocument");
    chrome.debugger.onEvent.addListener(onEvent);
});

function onEvent(debuggeeId, message, params) {
    if (message == "DOM.documentUpdated") {
        chrome.tabs.sendMessage(tabId, {
            "data": "getHTML"
        });
    }
}
chrome.extension.onMessage.addListener(function (response, sender) {
    console.log(response);
});

如何确保在测试期间不手动触发开发人员工具。

【讨论】:

  • TabId 由附加调试器并打开弹出窗口的 background.js 文件设置。我会将代码添加到原始帖子中。我尝试仅更改清单以包含“”,但其余部分似乎相同。唯一的其他区别是您将弹出窗口作为浏览器操作加载,而我使用 background.js 加载弹出窗口。
  • @ilya:您不是加载弹出窗口,您正在创建一个面板类型的新窗口,如何在创建新面板后绑定调试器会话
  • 没错。自从我尝试了你的方法后,我已经更改了术语,我不想要扩展的默认弹出窗口,而是想要一个新框架来显示结果。
  • 我能够实现您更正的内容,但这并没有按预期工作。 chrome.tabs.sendMessage(tabId, {"data": "getHTML"});不会在函数内被调用......或者如果它确实没有任何东西在听。当页面最终完成加载时,我可以通过控制台手动发送消息,然后我才能得到一些东西。任何想法为什么这没有发生? DOM 完全加载时的 tOt 值是否与 Dom.documentUpdated 不同?
  • @ilya:你能解释一下什么没有按预期工作吗?我对此进行了测试,并且能够跟踪调试器事件;您要跟踪什么?
【解决方案2】:

好的,我想通了。 由于我需要加载页面的 DOM,我将在我的后台页面中使用 chrome.tabs.onUpdated.addListener 在页面加载时发送代码。这样我就不必依赖选项卡和扩展程序之间的 2 路通信了。

清单

删除 content.js

background.js

添加了以下内容

chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
  if (tabId != _tabId) {return;}
  if (changeInfo.status == "complete") {
    chrome.tabs.executeScript(tabId, {code:"var x = document.documentElement.innerHTML;x"}, function (r) {
      chrome.extension.sendMessage(null, {"data": r[0]});       
    });
  }
});

content.js

已移除

spy.js

添加了以下内容

chrome.extension.onMessage.addListener(function(request, sender) {
  console.log("Request.data: " + request.data);
});

【讨论】:

  • 改标题帮助别人
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-03
  • 1970-01-01
相关资源
最近更新 更多