【问题标题】:Chrome Extension sendResponse callback value not being sentChrome 扩展程序 sendResponse 回调值未发送
【发布时间】:2016-05-16 05:24:35
【问题描述】:

我正在编写一个与 gmail api 交互的 chrome 扩展程序(chrome 45 是我的版本),我在将消息从 background.js 发送到我的内容脚本时遇到问题。异步方面是问题所在。回调后如何获取要发送的消息?

//---------in content script---------
chrome.runtime.sendMessage({ messageId: _id }, function (response) {    
    console.log('the respose.messagePayload is: ' + response.messagePayload); 
});

//---------in background script---------
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
    getMessage('me', request.messageId, function (payload) {
        //i want to send my response here
        //this executes and grabs the payload of data from the api, but isn't sending back the message to the content-script
        sendResponse({ messagePayload: payload }); 
    });
    //this synchronous call sends a message to the content-script
    //sendResponse({ messagePayload: "payload" });
    return true;
});

function getMessage(userId, messageId,callback) {
    var request = gapi.client.gmail.users.messages.get({
        'userId': userId,
        'id': messageId
    });
    request.execute(callback);
}

Chrome Extension Message passing: response not sent

【问题讨论】:

  • 您确定带有payload 的回调会执行吗?您可以通过日志记录确认吗?
  • @Xan 我可以确认该部分适用于日志记录。我有将其添加到 localStorage 并从 localStorage 读取的代码,但这是一种解决方法,因为我想在 sendResponse 'localStorage.setItem(request.messageId, JSON.stringify(payload)); 中发送对象sendResponse({ messagePayload: payload });'
  • @pacopicorico 您可以使用“chrome.storage”API 将您的响应存储为对象,而不是使用字符串化。您是否尝试过我发布的第二种方法,我认为这会很好,并且可以避免您将其存储到本地存储中。
  • @NikhilSharma 您的建议无效。它提出了我正在尝试寻找解决方案的相同问题。
  • @pacopicorico 如果您从 gmail API 获得响应并且您的 localstorage 解决方法有效,那么我的建议应该有效。您能否在发送和接收消息时发布您遇到的错误或从后台脚本和内容脚本发布日志。

标签: javascript google-chrome google-chrome-extension callback


【解决方案1】:

您应该在回调中发送sendResponse 函数。

getMessage('me', request.messageId, sendResponse);

然后在您的getMessage 调用完成时执行此操作。

function getMessage(userId, messageId, sendResponse) {
    var request = gapi.client.gmail.users.messages.get({
        'userId': userId,
        'id': messageId
    });

    request.execute(function(response) {
        sendResponse({messagePayload: response.payload});
    });
}

另一种可能的解决方案:

  1. sender 对象中获取tab id
  2. 只需将选项卡 ID 发送到您的 getMessage 函数,而不是回调函数。
  3. 现在,getMessage 函数中的回调函数会将有效负载发送回您的内容脚本。
  4. 在您的内容脚本中添加一个类似的 onMessage 侦听器,该侦听器将接收您的负载,然后对负载执行您想要执行的操作。

您的代码如下:

//---------in background script---------
chrome.runtime.onMessage.addListener(function (request, sender,sendResponse) {
    getMessage('me', request.messageId, sender.tab.id);
});

function getMessage(userId, messageId, tabId) {
    var request = gapi.client.gmail.users.messages.get({
        'userId': userId,
        'id': messageId
    });
    request.execute(function(response) {
        // Whatever response you want to sent
        // Below URL explains your response object
        // https://developers.google.com/gmail/api/v1/reference/users/messages#resource
        // Assuming you want to send payload
        chrome.tabs.sendMessage(tab.id, {messagePayload: response.payload});
    });
}

//---------in content script---------
chrome.runtime.sendMessage({ messageId: _id });

chrome.runtime.onMessage.addListener(function (request, sender,sendResponse) {
    // Just to verify that the request is from the getMessage callback
    // Because this will listen to all request from your extension
    if (request.messagePayload) {
        console.log('the respose.messagePayload is: ' + request.messagePayload);
    }
});

我希望这会有所帮助。

【讨论】:

  • 第一个解决方案是蛇油 - 关闭会解决这个问题。第二种解决方案是回避问题,并且不适用于 iframe;也有错误。
猜你喜欢
  • 1970-01-01
  • 2013-12-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多