【问题标题】:chrome.tabs.sendMessage not working while sendResponse workschrome.tabs.sendMessage 在 sendResponse 工作时不起作用
【发布时间】:2015-08-05 07:25:39
【问题描述】:

这是 chrome 扩展的清单:

{
  "name": "myconnector",
  "short_name": "myconnector",
  "version": "1.1",
  "manifest_version": 2,
  "description": "myapp",
  "background": {
    "scripts": ["main.js"],
    "persistent": true
    },
    "externally_connectable": {
      "ids": ["*"],
      "matches": ["*://*.myurl.fr/*"]
  },
  "web_accessible_resources": [ "emulation.js", "content_scripts.js" ],
  "icons": {
    "16": "icon-16.png",
    "128": "icon-128.png"
  },
  "permissions": [
    "tabs",
    "nativeMessaging"
  ]
}

chrome扩展的背景页面:

//------ Message received from external web site

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

    if(request.areYouThere) {
        onNativeMessage(true);
    }

    if(!port) {
        port = chrome.runtime.connectNative(hostName);
        //port.onMessage.addListener( onNativeMessage );
    }

    port.onMessage.addListener(function(msg) {sendResponse(msg);});

     port.onDisconnect.addListener(function() {
        console.log("Disconnected from native App");
        port = null;
    });

    if (request.data) {
      var data = request.data;
      console.log(JSON.stringify(request));
      port.postMessage(data);
    }

    return true;

  });

// ----- Message received from Native Host App

function onNativeMessage( message ) {
    console.log( 'received message from native app: ' + JSON.stringify( message ) );
    chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
        chrome.tabs.sendMessage(tabs[0].id, message, function(response){});
    });
}

这里是调用扩展的网站代码:

$("#my-action").click(function(){

            console.log("calling method MyAction");

            chrome.runtime.sendMessage( "<extension id>",  
                                {data: 
                                    {action:"MyAction"}
                                    }, 
                                function(response) {
                console.log(JSON.stringify(response));
                $("#result").text(JSON.stringify(response));
            });
        });

当我这样做时:

port.onMessage.addListener(function(msg) {sendResponse(msg);});

响应已正确发送,但我收到 chrome.native.lastError.message :

每个 chrome.runtime.onMessage 不能多次发送响应 每个文档的侦听器(消息是由 URL 的扩展发送的 未定义)。

但是当我这样做时:

port.onMessage.addListener( onNativeMessage );

此方法调用 onNativeMessage 使用方法 chrome.tabs.sendMessage 将消息发送回网站(据称?)。但该网站从未得到响应。

此外,我的扩展程序需要实例化一个端口,以便它可以使用与我的本地主机应用程序的长期连接。

我做错了吗?

【问题讨论】:

  • 这是一个扩展,而不是一个应用。相应地修改问题。

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


【解决方案1】:

当我这样做时:

port.onMessage.addListener(function(msg) {sendResponse(msg);});

响应已正确发送,但我收到 chrome.runtime.lastError.message

每个文档的每个 chrome.runtime.onMessage 侦听器不能多次发送响应(消息是通过未定义 URL 的扩展发送的)。

那是因为您每次收到外部消息时都会添加一个侦听器。所以在收到第二条消息后,sendResponse() 会尝试运行两次(新的和旧的)。


但是当我这样做时:

port.onMessage.addListener( onNativeMessage );

此方法调用onNativeMessage 使用方法chrome.tabs.sendMessage 将消息发送回网站(据称?)。但该网站从未得到响应。

你不能那样做; chrome.tabs.sendMessagecontent script context 发送消息,而不是网页。


您应该修改您的代码,只添加一次侦听器,或者至少确保一次只有一个侦听器。

当然,诀窍在于sendResponse 引用每次都会更改。我想您可以使用自注销侦听器来做到这一点:

if(!port) {
    port = chrome.runtime.connectNative(hostName);

    port.onDisconnect.addListener(function() {
      console.log("Disconnected from native App");
      port = null;
    });
}

var callback = function(msg) {
  sendResponse(msg);
  port.onMessage.removeListener(callback); // The power of closures!
};

port.onMessage.addListener(callback);

【讨论】:

  • 非常感谢您快速而详尽的回答。像魅力一样工作。
  • 亲爱的@Xan,我有一个扩展(作为我的背景)与外部页面(作为我的内容脚本)进行通信。如何在内容脚本端终止监听?我正在使用 port.onMessage.removeListener(this); ,但是它不起作用!
  • @Aqjn 提出一个更详细的新问题,不要尝试在 cmets 中提出后续问题。
猜你喜欢
  • 2013-12-24
  • 2016-04-24
  • 1970-01-01
  • 1970-01-01
  • 2022-12-31
  • 2022-06-23
  • 1970-01-01
  • 2016-04-16
  • 1970-01-01
相关资源
最近更新 更多