1

Edit: I have been banned for asking this question, I'm not sure why or how to improve it — I think it's pretty specific and on topic. Help? Apparently it's a duplicate, so does that mean I should delete it? But I've read it's against the rules to delete? I really don't understand.

I have a Chrome extension with a background and content script. The content script sends url to the background script fine, which talks to a .py script and creates new variable myPubscore. I'm trying to send myPubscore back to the content script.

The docs give an example where the background script sends {greeting:"farewell"} to the content script, which works fine for me. But when I replace {greeting:"farewell"} with {score: myPubscore}, I get "undefined".

content.js

    chrome.runtime.sendMessage({ "type": "articleUrl", "url": url }, function (response) {
        console.log("here's the response for sending the URL");
        console.log(response);
    });

background.js

chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
    if (request.type == "articleUrl") {
        console.log("background heard articleUrl")
        console.log(request);
        var articleUrl = request;
        $.ajax({
        type: 'POST',
        url: `${url}/buttoncolor`,
        data: articleUrl,
        success: function urlFunction(data) {
        var myPubscore = data;
        console.log("myPubscore:")
        console.log(myPubscore);
        }
        })
    sendResponse({score: myPubscore});
    }
...
codi6
  • 516
  • 1
  • 3
  • 18

1 Answers1

3

Essentially what is happening is the port is closing before the asynchronous ajax request can be fulfilled. To resolve this you can send messages from the background script similar to the content script.

content.js

chrome.runtime.onMessage.addListener((message) => {
    console.log('sent from background', message.farewell);
});

chrome.runtime.sendMessage({ "type": "articleUrl", "url": url }, function (response) {
    console.log("here's the response for sending the URL");
    console.log(response);
});

background.js

chrome.runtime.onMessage.addListener((message, sender) => {
  const { type, url } = message;
  const tabId = sender.tab.id;

  // your business logic
  ...
  chrome.tabs.sendMessage(tabId, { farewell: 'goodbye' });
});

You could create a message port to keep a connection between the background script and the content script if in the future you need a longer lasting connection.

More information on message ports: https://developer.chrome.com/extensions/messaging#connect

jasonandmonte
  • 1,869
  • 2
  • 15
  • 24
  • Thanks, I'll fiddle with that. Is it also an issue that my variable is in the AJAX but possibly not making it to the sendResponse? – codi6 May 14 '20 at 00:41
  • To clarify: "farewell" is sending just fine, and I'm getting no errors. But myPubscore isn't sending. – codi6 May 14 '20 at 00:46
  • Just tried your code --- I'm still getting undefined and the error message. Are you sure it's the ports? Again, message "farewell" sent just fine from the beginning, it's when I try to send myPubscore that I get problems. – codi6 May 14 '20 at 00:55
  • 1
    Right, it's due to the ajax call being asynchronous. You can add the `sendMessage` as a callback of your success function. Or rewrite your ajax call using `async/await`. – jasonandmonte May 14 '20 at 01:04
  • Couldn't get it working yesterday, but it worked today! Thanks much! – codi6 May 14 '20 at 17:12
  • Hey! Noticed an issue — instead of sending the one message associated with a given background script response, it seems to send a bunch of duplicate messages to the content.js script. – codi6 May 15 '20 at 01:47
  • Why doesn't using sendResponse just work? My sendMessage in the content script is actually executed in a function and the response is supposed to be returned in the function, so I can't use multiple sendMessages. – IMPixel Jun 24 '23 at 00:46