sendResponse有效时,chrome.tabs.sendMessage无效

时间:2015-08-05 07:25:40

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

以下是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方法将消息发送回网站(据称?)。但该网站从未得到回复。

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

我做错了吗?

1 个答案:

答案 0 :(得分:2)

  

当我这样做时:

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);