Chrome Devpanel Extension Communicating with Background Page

后端 未结 1 1416
礼貌的吻别
礼貌的吻别 2020-12-07 16:53

I have an extension to the chrome devtools panel. I can send messages to the page using chrome.devtools.inspectedWindow.eval ... but how do I receive messages i

相关标签:
1条回答
  • 2020-12-07 17:33

    The goal is to create a channel ("port") for communication. It does not matter how the port is created, as long as the connection is correctly maintained.

    The devtools script has to initiate the port, because the background script does not know when a devtools panel is created.

    Here's a basic example, which shows a bidirectional communication method:

    devtools.js

    chrome.devtools.panels.create('Test', '/icon.png', '/panel.html', function(extensionPanel) {
        var _window; // Going to hold the reference to panel.html's `window`
    
        var data = [];
        var port = chrome.runtime.connect({name: 'devtools'});
        port.onMessage.addListener(function(msg) {
            // Write information to the panel, if exists.
            // If we don't have a panel reference (yet), queue the data.
            if (_window) {
                _window.do_something(msg);
            } else {
                data.push(msg);
            }
        });
    
        extensionPanel.onShown.addListener(function tmp(panelWindow) {
            extensionPanel.onShown.removeListener(tmp); // Run once only
            _window = panelWindow;
    
            // Release queued data
            var msg;
            while (msg = data.shift()) 
                _window.do_something(msg);
            // Just to show that it's easy to talk to pass a message back:
            _window.respond = function(msg) {
                port.postMessage(msg);
            };
        });
    });
    

    Now, the panel is capable of sending/receiving messages over a port. The panel's script (external script file, because of the CSP) may look like:

    panel.js

    function do_something(msg) {
        document.body.textContent += '\n' + msg; // Stupid example, PoC
    }
    document.documentElement.onclick = function() {
        // No need to check for the existence of `respond`, because
        // the panel can only be clicked when it's visible...
        respond('Another stupid example!');
    };
    

    Now, the background page's script:

    background.js

    var ports = [];
    chrome.runtime.onConnect.addListener(function(port) {
        if (port.name !== "devtools") return;
        ports.push(port);
        // Remove port when destroyed (eg when devtools instance is closed)
        port.onDisconnect.addListener(function() {
            var i = ports.indexOf(port);
            if (i !== -1) ports.splice(i, 1);
        });
        port.onMessage.addListener(function(msg) {
            // Received message from devtools. Do something:
            console.log('Received message from devtools page', msg);
        });
    });
    // Function to send a message to all devtools.html views:
    function notifyDevtools(msg) {
        ports.forEach(function(port) {
            port.postMessage(msg);
        });
    }
    

    To test, simply run notifyDevtools('Foo'); on the background page (e.g. via the console). In this demo, the message will be sent to all devtools. Upon receipt, the devtools panel will contain the received message.

    Put the extension together using:

    manifest.json

    { "name": "Test",
      "manifest_version": 2,
      "version": "1",
      "devtools_page": "devtools.html",
      "background":{"scripts":["background.js"]}
    }
    

    panel.html

    <script src="panel.js"></script> <!-- Doctype etc not added for conciseness-->
    

    devtools.html

    <script src="devtools.js"></script>
    

    See also

    • How to modify content under a devtools panel in a Chrome extension?
    • chrome.devtools API
    • Message passing: Long-lived connections
    • Content Security Policy in Chrome extensions ("Inline JavaScript (...) will not be executed. This restriction bans both inline <script> blocks and inline event handlers.")
    0 讨论(0)
提交回复
热议问题