在扩展程序中,Chrome DevTools 和内容脚本之间的通信

8
我已经阅读了this,但它没有起作用,我进行了大量的搜索和尝试,但都无济于事。
我正在编写一个Chrome扩展程序(BigConsole),旨在为Chrome开发者工具构建更好的控制台选项卡。这意味着我想在页面上下文中执行用户输入的代码,并访问页面上的DOM和其他变量。为了做到这一点,通信结构如下:
  • devtools 创建一个 panel,用户在其中编写代码
  • 当用户想要执行来自 panel 的代码时,panelbackground 脚本发送一条消息,其中包含代码
  • background 脚本接收来自 panel 的消息/代码,并将其传递给注入到页面中的 content 脚本
  • content 脚本接收来自 background 脚本的消息/代码,并在页面中注入一个 script 元素,然后运行代码
  • 页面上 script 的结果随后通过 window.postMessage 发送回 content 脚本
  • content 脚本监听页面的消息/结果,并将其传递给 background 脚本
  • background 脚本接收来自 content 脚本的消息/结果,并将其传递给 panel
  • panel 接收来自 background 脚本的消息/结果,并将其插入到结果日志中

哎呀。

现在,当用户尝试运行代码时,什么也不会发生。我在代码中放了一堆console.log(),但控制台中没有任何东西出现。我的主要问题是,在消息传递方面我做错了什么导致什么都没有发生?或者,我很想被告知我正在把事情搞得太复杂了,有更好的方法来做这件事。下面是简化后的代码...

panel.js:

    window.onload = function() {
      var port = chrome.runtime.connect({name: "Eval in context"});
      // Add the eval'd response to the console when the background page sends it back
      port.onMessage.addListener(function (msg) {
        addToConsole(msg, false);
      });
      document.getElementById('run').addEventListener('click', function() {
        var s = document.getElementById('console').value;
        try {
          // Ask the background page to ask the content script to inject a script
          // into the DOM that can finally eval `s` in the right context.
          port.postMessage(s);
          // Outputting `s` to the log in the panel works here,
          // but console.log() does nothing, and I can't observe any
          // results of port.postMessage
        }
        catch(e) {}
      });
    };

background.js:

    chrome.runtime.onConnect.addListener(function (port) {
      // Listen for message from the panel and pass it on to the content
      port.onMessage.addListener(function (message) {
        // Request a tab for sending needed information
        chrome.tabs.query({'active': true,'currentWindow': true}, function (tabs) {
          // Send message to content script
          if (tab) {
            chrome.tabs.sendMessage(tabs[0].id, message);
          }
        });
      });
      // Post back to Devtools from content
      chrome.runtime.onMessage.addListener(function (message, sender) {
        port.postMessage(message);
      });
    });

content.js:

    // Listen for the content to eval from the panel via the background page
    chrome.runtime.onMessage.addListener(function (message, sender) {
      executeScriptInPageContext(message);
    });
    function executeScriptInPageContext(m) { alert(m); }
1个回答

5

正如Alex所指出的那样,您的代码中有一个错别字导致它无法工作。

放弃当前的代码并使用chrome.devtools.inspectedWindow.eval直接运行代码并解析结果。这简化了您复杂的逻辑:

  • devtools创建一个面板供用户编写代码
  • devtools运行代码
  • devtools处理结果

PS. 有一种方法可以操作现有的控制台,但我建议不要使用它,除非是个人使用。在此答案中展示了两种不同的方法。


太棒了,谢谢!如果你不仅能向我展示一个更好的官方方法,而且还能向我展示一个更好的非官方方法,那就更加赚到了!:) - IceCreamYou

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接