Search code examples
htmlgoogle-chrome-extension

Getting the source HTML of the current page from chrome extension


I have a chrome extension. I need to analyse from the HTML source of the current page. I found here all kinds of solutions with background pages and content scripts but none helped me. here is what I have so far:

manifest.json

{
  "name": "Extension",
  "version": "1.0",
  "description": "Extension",
  "browser_action": {
    "default_icon": "bmarkred.ico",
    "popup": "Test.html"
  },
  "content_scripts": [
    {
      "matches": ["http://*/*"],
      "js": ["content.js"]
    }
  ],
  "background": {
    "page": "backgroundPage.html"
  },
  "permissions": [
    "cookies",
    "tabs",
    "http://*/*", 
    "https://*/*"
  ]
}

background.html

<html>
<head>
<script type="text/javascript">
    try {
        chrome.tabs.getSelected(null, function (tab) {
            chrome.tabs.sendRequest(tab.id, {action: "getSource"}, function(source) {
                alert(source);
            });
        });
    }
    catch (ex) {
        alert(ex);
    }
</script>
</head>
</html>

content.js

chrome.extension.onRequest.addListener(function(request, sender, callback) {
    if (request.action == "getSource") {
        callback(document.getElementsByTagName('html')[0].innerHTML);
    }
});

The alert always alerts undefined. even if i change in the content.js file the callback function to:

callback('hello'); 

still the same result. What am I doing wrong? maybe I'm going at this the wrong way. What I really need is this: When the user opens the extension popup (and only then), I need HTML of the current page so I can analyse it.


Solution

  • Inject a script into the page you want to get the source from and message it back to the popup....

    manifest.json

    {
        "name": "Get pages source",
        "version": "1.1",
        "manifest_version": 3,
        "description": "Get active tabs or element on that pages source from a popup",
    
        "action": {
            "default_title": "Get pages source",
            "default_popup": "popup.html"
        },
    
        "permissions": [
            "scripting",
            "activeTab"
        ]
    }
    
    

    popup.html

    function onWindowLoad() {
        var message = document.querySelector('#message');
    
        chrome.tabs.query({ active: true, currentWindow: true }).then(function (tabs) {
            var activeTab = tabs[0];
            var activeTabId = activeTab.id;
    
            return chrome.scripting.executeScript({
                target: { tabId: activeTabId },
                // injectImmediately: true,  // uncomment this to make it execute straight away, other wise it will wait for document_idle
                func: DOMtoString,
                // args: ['body']  // you can use this to target what element to get the html for
            });
    
        }).then(function (results) {
            message.innerText = results[0].result;
        }).catch(function (error) {
            message.innerText = 'There was an error injecting script : \n' + error.message;
        });
    }
    
    window.onload = onWindowLoad;
    
    function DOMtoString(selector) {
        if (selector) {
            selector = document.querySelector(selector);
            if (!selector) return "ERROR: querySelector failed to find node"
        } else {
            selector = document.documentElement;
        }
        return selector.outerHTML;
    }