Reputation: 43
I'm looking for a bit of help here as the examples I've seen have only been from the tab to the extension and not the other way around.
I'm looking to grab the source code of a page/tab that I am debugging with a custom Chrome Extension. I want the extension to call a message and the response to be sent back to the extension panel javascript making the call.
Manifest
"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);});
}
Result
Port error: Could not establish connection. Receiving end does not exist. miscellaneous_bindings:235 chromeHidden.Port.dispatchOnDisconnect miscellaneous_bindings:235
Error in event handler for 'undefined': Cannot read property 'data' of undefined TypeError: Cannot read property 'data' of undefined
at chrome-extension://fpdkndicjblnkakkiiapbbdflkehjmgm/headers.js:132:91
at miscellaneous_bindings:279:11
at chrome.Event.dispatchToListener (event_bindings:387:21)
at chrome.Event.dispatch_ (event_bindings:373:27)
at chrome.Event.dispatch (event_bindings:393:17)
at Object.chromeHidden.Port.dispatchOnDisconnect (miscellaneous_bindings:238:27)
I get this error when I try to run it. What am I missing?
Upvotes: 2
Views: 3387
Reputation: 43
OK I've figured it out. Since I need the DOM of the loaded page, I'm going to use the chrome.tabs.onUpdated.addListener in my background page to send the code when the page is loaded. This way I don't have to depend on the 2 way communication between the tab and extension.
Manifest
Removed content.js
background.js
Added the following
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
REMOVED
spy.js
Added the following
chrome.extension.onMessage.addListener(function(request, sender) {
console.log("Request.data: " + request.data);
});
Upvotes: 1
Reputation: 18534
How are you capturing tabId
of chrome.tabs.sendMessage(tabId,
, can you post your full script to debug problem,if you are looking for a sample code for passing message from Chrome Extension
to Debugging Tab
check this.
Registered popup
page and 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
}
Ensured HTML Adheres to 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>
Pass Message to Content Scripts.
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;
});
Added a handler to catch messages sent from popup page
//Add a handler to handle message sent from popup.html
chrome.extension.onMessage.addListener(function(request, sender) {
console.log("Message "+request+" is recieved");
});
I got your code working after eliminates some deprecated API() like 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);
});
How ever ensure you do not trigger developer tools manually during testing.
Upvotes: 1