chrome extension `sendResponse` does not work
Asked Answered
B

3

10

I am writing a chrome extension but the sendResponse method does not work.

chrome.runtime.onMessage.addListener(
    function(request, sender, sendResponse) {

            if(!request.method){
                    return false;
            }

            if(request.method=='postList' && request.post_list){
                // alert(1);                                                                                                                                                                            
                    a_facebook_api.getPostFromDB(request.post_list, function(data){
                            alert(data);                                                                                                                                                              
                            sendResponse(data);                                                                                                                                                       
                          
                    });

            } else if(request.method=='postAdd' && request.post_data){
                    a_facebook_api.addPostToDB(request.post_data, function(data){

                            sendResponse(data);
                    });

    }

            return true;

}
);

 chrome.runtime.sendMessage({method: "postList",post_list: post_list}, function(response) {

         alert(response);
                                                                                                                                                           
            });

the function alert(data) works. It gives me proper data with JSON format. However, the alert(response) does not show any message. Can anyone give me some ideas why it isn't working?

Thank you in advance!

Bigener answered 6/12, 2013 at 23:38 Comment(1)
Related, not a duplicate: Chrome Extension Message passing: response not sent. However, if you're here because you searched for a problem like this, that question has your most likely answer.Wallinga
L
18

You haven't stated weather you this code is in the content script or the background page. From looking at it I assume it it part of the content script.

I tried your code in one of my own extensions and it alerted "[object Object]" which is what happens when you alert a variable that isn't a string or numerical value. If you change the alert data to "response.responseData" it will alert the value you labeled "responseData" from the background page.

As it wasn't alerting anything for you I think that the script that is listening for the message is not responding properly.

I got the code working. This is the content script:

//Document ready
window.onload = function() {
    alert('Ready');
    //Send a message
    sendMessage();
}

//Get message from background page
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
    //Alert the message
    alert("The message from the background page: " + request.greeting);//You have to choose which part of the response you want to display ie. request.greeting
    //Construct & send a response
    sendResponse({
        response: "Message received"
    });
});

//Send message to background page
function sendMessage() {
    //Construct & send message
    chrome.runtime.sendMessage({
        method: "postList",
        post_list: "ThePostList"
    }, function(response) {
        //Alert the message
        alert("The response from the background page: " + response.response);//You have to choose which part of the response you want to display ie. response.response
    });
}

This is the background script:

//Get message from content script
chrome.runtime.onMessage.addListener(
    function(request, sender, sendResponse) {
        //Alert the message
        alert('The message from the content script: ' + request.method);//You have to choose which part of the response you want to display ie. request.method
        //Construct & send a response
        sendResponse({
            response: "Message received"
        });
    }
);

//Send message to content script
function sendDetails(sendData) {
    //Select tab
    chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
        //Construct & send message
        chrome.tabs.sendMessage(tabs[0].id, {
            greeting: sendData
        }, function(response) {
            //On response alert the response
            alert("The response from the content script: " + response.response);//You have to choose which part of the response you want to display ie. response.response
        });
    });
}

Every time a script receives a message you have to use the "sendResponse" function to send a response.

Hope this helped.

Leavelle answered 3/3, 2014 at 19:36 Comment(0)
W
11

This same question Chrome Extension Message passing: response not sent will help.

You just need to add return true on listener.

Wilow answered 6/1, 2016 at 8:55 Comment(3)
This worked for me! thanks for posting your solutionAnibalanica
If you see a question that can be answered with the same answer as another question, please flag the question as a duplicate; don't add an answer. However, as can be seen in the code in the question, the OP already does return true; in their listener. Thus, this is not the answer to this question, but it's the answer to many people who have the same problem.Wallinga
I would call it a different problem but with a similar symptom. Here the issue was with how the OP chose to display the data. That is not solved with return true; as Makyen stated. Chrome will trash sendResponse after the message listeners finish. Which is a whole different problem when the need is to use another asynchronistic call before sendResponse... In this case, return true; tells chrome to run sendResponse asynchronously (aka. keeping the sendReponse callback channel open). It will keep it valid until it gets invoked. Also, automatic sendResponse invocation gets disabled.Roscoeroscommon
L
1

I was looking for the solution to get data from content script inside the popup. Yes, you can have it with storage, but this is applied to all tabs, so better to send message to active tab, and read response:

inside popup.js

chrome.tabs.query({
    active: true,
    lastFocusedWindow: true
}, function (tabs) {
    chrome.tabs.sendMessage(tabs[0].id, {data: 1}, function (response) {
        console.log(response.data)
    });
});

inside content.js

chrome.runtime.onMessage.addListener(function (message, sender, sendResponse) {
    if (message.data === 1) {
        // accepts only 1 field
        sendResponse({
            data: 2
        });
        // very important to return true 
        return true; 
    }
});
Loginov answered 2/1, 2019 at 21:48 Comment(2)
Despite the urban myth propagated by some people, "return true" is needed only when calling sendResponse in an asynchronous code inside onMessage. In other words it's not needed in this answer's code.Slicker
bro, is lastFocusedWindow needed, if I have 4 tabs open for the same page, I only want the currently viewed tab to have a message sent using the chrome.tabs.sendMessageChiropody

© 2022 - 2024 — McMap. All rights reserved.