joe joe - 14 days ago 7
Javascript Question

Struggling to get DOM data in Chrome extension

I have found several quite well up-voted questions here on Stack Overflow, though I can't actually find a working solution.

I've been trying to follow the answer here: Chrome Extension - Get DOM content,
but I still get a completely blank console (despite reloading the extension)!

manifest.json:

{
"manifest_version": 2,
"name": "Test Extension",
"version": "0.0",
"background": {
"persistent": false,
"scripts": ["background.js"]
},
"content_scripts": [{
"matches": ["https://*/*"],
"js": ["content.js"]
}],
"browser_action": {
"default_title": "Test Extension",
"default_icon": "icon.png",
"default_popup": "popup.html"
},

"permissions": ["activeTab"]
}


background.js:

// A function to use as callback
function logDOM(domContent) {
console.log('I received the following DOM content:\n' + domContent);
}

// When the browser-action button is clicked...
chrome.browserAction.onClicked.addListener(function (tab) {
console.log(tab.url);
chrome.tabs.sendMessage(tab.id, {text: 'report_back'}, logDOM);

});


content.js:

// Listen for messages
chrome.runtime.onMessage.addListener(function (msg, sender, sendResponse) {
// If the received message has the expected format...
if (msg.text === 'report_back') {
// Call the specified callback, passing
// the web-page's DOM content as argument
sendResponse(document.all[0].outerHTML);
}
});


Am I doing something wrong?

Answer

Remove default_popup from browser_action:
The problem is that you are defining a default_popup for the browser_action in your manifest.json. Change the browser_action to:

"browser_action": {
  "default_title": "Test Extension",
  "default_icon": "icon.png"
},

If you define a default_popup, then Chrome tries to display the popup and does not send a click event to your background script. You should have seen a popup displayed saying that your file was not found.

Only injecting into https scheme pages:
Given that you are only injecting your content script into https:// pages, make sure you are testing on a page that is using the https scheme.

You may find it easier to test by injecting your content script into all URLs. You can do so by changing the content_script key in your manifest.json to:

"content_scripts": [{
  "matches": ["<all_urls>"],
  "js": ["content.js"]
}],

It is also not injected into pages in the chrome scheme (e.g. chrome://extensions/) (even when using <all_urls>). Thus, your extension will not work on those pages.

You must load content page after loading the extension:
You will also need to make sure you have reloaded the page, opened a new tab, or navigated to a new page after loading, or reloading, the extension. Your content script is not injected into already loaded pages.

The Output is in the console for your background page:
In addition, you will need to be looking at the console for your background page. There are multiple consoles which you might need to be looking at depending on in which context/scope you are calling console.log(). The answer linked in the first sentence of this section describes how to view them.

manifest.json with all mentioned changes:

{
  "manifest_version": 2,
  "name": "Test Extension",
  "version": "0.0",
  "background": {
    "persistent": false,
    "scripts": ["background.js"]
  },
  "content_scripts": [{
    "matches": ["<all_urls>"],
    "js": ["content.js"]
  }],
  "browser_action": {
    "default_title": "Test Extension",
    "default_icon": "icon.png"
  },

  "permissions": ["activeTab"]
}
Comments