【问题标题】:Chrome extension: sendMessage doesn't workChrome 扩展程序:sendMessage 不起作用
【发布时间】:2014-06-01 01:53:07
【问题描述】:

我已经多次阅读 Google 提供的有关“消息传递”的文档,并且可能已经查看了 10 多个具有相同问题的其他问题,并且已经尝试过对其大多数“解决方案”的一些变体以及什么我有下面...这是黑魔法,对吧?无论哪种方式,都可以。

清单文件:

{
    "manifest_version" : 2,
    "name" : "Message Test",
    "version" : "1.0",

    "browser_action": { 
        "default_popup": "popup.html"
    },

    "background": {
        "scripts": ["background.js"]
    },

    "content_scripts": [
        {
        "matches" : ["<all_urls>"],
        "js": ["message-test.js"]
        }
    ]    
}

我知道扩展不应该使用内联 JS,但我将其保留,因此可以保留原来的问题,因为我仍然无法从后台页面发送消息,当我从弹出窗口切换到后台时,我从 manifest.json 中删除了相应的行

popup.html 文件:

<html>
  <head>
    <script>
    chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
      chrome.tabs.sendMessage(tabs[0].id, {greeting: "hello", theMessage: "Why isn\'t this working?"}, function(response) {
        console.log(response.farewell);
      });
    });
    </script>
  </head>
<body>
</body>
</html>

background.js 文件:

chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
  chrome.tabs.sendMessage(tabs[0].id, {greeting: "hello", theMessage: "Why isn\'t this working?"}, function(response) {
    console.log(response.farewell);
  });
});

message-test.js 文件:

var Mymessage;
chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) {
    if (message.greeting == "hello"){
        Mymessage = message.theMessage;
        alert(Mymessage);
    }
    else{
        sendResponse({});
    }
});

我收到一个未定义的警报...

在按下弹出窗口中的按钮并在指定的 url 处有一个窗口后,我也尝试执行此操作,但这是稍后的问题。按钮和窗口的其他文件可以在这里找到,除了 background.js 内容包含在 addEventListener("click"....: http://pastebin.com/KhqxLx5yhttp://pastebin.com/JaGcp6tj

【问题讨论】:

  • all_urls 语法无效
  • @ZigMandel 碰巧就是这样。
  • @hucuhy 感谢您提出这个问题。自今天(2014 年 6 月 3 日)发布此消息以来,我仍未收到有用的回复。在点击默认弹出窗口中的按钮后,能够从后台页面向内容脚本发送消息对于知道这些东西如何工作的人来说似乎并不难......

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


【解决方案1】:

您的代码中有几个问题。

Chrome 不允许在扩展程序中使用内联脚本。您必须将您的 popup.html 划分为 script + HTML:

// popup.html
<html>
<body>
<script type="text/javascript" src="popup.js"></script>
</body>
</html>

// popup.js
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
    var tab = tabs[0];  // do not forget to declare "tab" variable
    chrome.tabs.sendMessage(tab.id, {
        greeting: "Can you hear me?"
    }, function(response){});
});

【讨论】:

  • 要添加到这个答案,如果您检查弹出窗口的开发者控制台,通过右键单击您的按钮并选择“检查弹出窗口”,您可能已经发现了错误。
  • "activeTab" 不是必需的,因为弹出窗口正在与现有的内容脚本通信,它不会尝试插入新的。
  • 所以我逐字尝试,它仍然不起作用...完全相同的“manifest.json”文件,相同的“message-test.js”文件...我复制并粘贴你的 popup.html 和你的 popup.js。没有警报响起。
  • 你们知道我还应该尝试什么吗?
  • @user3334776 在进行更改后,您是否正确地重新加载了您的扩展程序,并重新加载了您正在测试要注入的新内容脚本的页面?
【解决方案2】:

仔细阅读this answer可能会对您有所帮助。那里的每一点都适用于您的问题。

您的问题在于您的主脚本何时执行,以及您的内容脚本何时执行。在向它发送消息之前,您需要确保有一个内容脚本在监听,最坏的情况是通过编程方式注入它。

要让它在弹出窗口中运行,请关注KAdot's answer

【讨论】:

    【解决方案3】:

    这是解决方案,使用后台脚本:

    manifest.json

    {
        "manifest_version" : 2,
        "name" : "Message Test",
        "version" : "1.0",
    
        "background":{
            "scripts":["popup.js"]
        },
    
        "content_scripts": [
            {
            "matches" : ["<all_urls>"],
            "js": ["message-test.js"]
            }
        ]
    }
    

    message-test.js

    var port = chrome.runtime.connect();
    port.onMessage.addListener(function(message, sender, sendResponse) {
        if (message.greeting == "Can you hear me?"){
            alert("Test");
        }
        else{
            sendResponse({});
        }
    });
    

    popup.js

    chrome.runtime.onConnect.addListener( function ( port ) {
    port.postMessage({
            greeting: "Can you hear me?"
        });
    });
    

    一些解释:首先我们从内容脚本连接到我们的后台脚本,然后后台脚本将消息发送到内容脚本。

    更新

    我根据@Xan 的评论改进了答案。但是思路是一样的,首先你要让你的后台脚本知道你的内容脚本的存在。

    【讨论】:

    • 使用打开端口只是敲门感觉……不对。
    • @Xan 对不起什么?)你知道用后台脚本交流的其他方式吗?)
    • 如果您不使用生成的端口,为什么要使用 chrome.runtime.connect / chrome.runtime.onConnect
    • 我正在使用运行时连接连接到后台脚本,直到后台脚本对内容脚本一无所知。
    • 错误。您可以使用connect / onConnect 并通过端口工作,也可以使用sendMessage / onMessage 并使用它。无需打开并立即丢弃端口。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-03-12
    • 2012-06-03
    • 1970-01-01
    • 2015-01-16
    • 2020-05-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多