Chrome extended message passing between content and background not working

I am developing a chrome extension, here are the main files:

background.js

 getPageDimension = function (){ chrome.tabs.getSelected(null, function(tab) { chrome.tabs.sendMessage(tab.id, { message: "DIMENSION" }, function(response){ if (response != null) { console.log(response.x); console.log(response.y); console.log(response.w); console.log(response.h); }else{ console.log('Response is null'); } }); }); }; 

content.js

 chrome.runtime.onMessage.addListener(function(msg, sender, sendResponse) { if (msg.message && (msg.message == "DIMENSION")) { var dimension = getPageDiemension(document.documentElement); console.log(dimension.x); console.log(dimension.y); console.log(dimension.w); console.log(dimension.h); sendResponse({x: dimension.x, y: dimension.y,w: dimension.w,h: dimension.h}); } }); getPageDiemension = function(currentDom){ var dimension = new Object(); dimension.x = 0; dimension.y = 0; dimension.w = currentDom.scrollWidth; dimension.h = currentDom.scrollHeight; return dimension; } 

So, my goal is to get the full height and width of the page loaded in the current active tab. When I debug my script content, I get the correct answer in my background.js , but if you run the script without debugging, I get an undefined answer in my background.js .

Here is the declaration of my cotent.js in my manifest.json file:

 "content_scripts": [{ "all_frames": true, "matches": [ "http://*/*", "https://*/*" ], "js": ["content.js"] }], 

Please help me, where am I mistaken? Let me know if you need more details.

+5
source share
1 answer

Questions

There are two small problems in your code that I found after wile, as this seems to work perfectly (when it is not at all).

  • You are using the deprecated chrome.tabs.getSelected(...) method, which should be avoided. Use chrome.tabs.query({active: true, highlighted: true}, ...) instead.
  • In your chrome.runtime.onMessage listener in the script content, you do some calculations before sending a response: this makes the message channel closed before you can send a response, and will result in a null response.

    Quote from the official documentation :

    This function ( sendResponse ) becomes invalid when the event receiver returns, unless you return true from the event listener to indicate that you want to send the response asynchronously (this will keep the message channel open at the other end, while sendResponse ).

Decision

Now that you know what the problem is, you can easily replace the old tabs.getSelected() with tabs.query() and add the return true; to the runtime.onMessage event runtime.onMessage in your script content. The solution is this: I made the code a bit easier.

Your background.js :

 getPageDimension = function (){ chrome.tabs.query({active: true, highlighted: true}, function(tabs) { chrome.tabs.sendMessage(tabs[0].id, { message: "DIMENSION" }, function(response){ if (response !== null) console.log('Response:', response); else console.log('Response is null'); }); }); }; 

Your content.js :

 chrome.runtime.onMessage.addListener(function(msg, sender, sendResponse) { if (msg.message && (msg.message == "DIMENSION")) { var dimension = getPageDiemension(document.documentElement); console.log('Dimension:', dimension); sendResponse(dimension); } return true; }); getPageDiemension = function(currentDom){ return { x: 0, y: 0, w: currentDom.scrollWidth, h: currentDom.scrollHeight } } 

Working example

You can find a working example that I made for testing HERE .

Documentation Links

Just for the sake of clarity, I leave you links to documentation regarding the APIs involved in this extension, which may be useful:

+9
source

Source: https://habr.com/ru/post/1210580/


All Articles