Chrome扩展程序:如何从面板向内容脚本发送消息

4
我的contentScript向backgroundScript发送一条消息,后者会打开一个弹出窗口/面板/窗口。该面板会加载一个外部网页。我正在向该面板注入一些JavaScript以与其交互。
现在我想要做到的是将数据从面板发送到“主页面”(contentScript)。我已经成功地将消息从面板发送到了backgroundScript。
我不明白/不知道的是如何将数据从backgroundScript传递到contentScript。
@Haibara Ai的评论中更新的脚本如下:
manifest.js
{
"name": "My extension",
"version": "0.1",
"manifest_version": 2,
"description": "description",
"permissions": ["activeTab", "tabs","http://*/*","https://*/*"],
"content_scripts": [
    {
        // Change 'matches' attribute to load content
        // script only in pages you want to.
        "matches": ["SomeUrl"],
        "js": ["jquery.min.js", "contentscript.js", "notifier.js"]
    }
],
"background": {
    "scripts": ["eventPage.js"],
    "persistent": false
}
}

contentscript.js

$(document).ready(function() {
    var link = document.getElementById('inputLink');

    // onClick's logic below:
    link.addEventListener('click', function() {
        chrome.runtime.sendMessage({
            action: 'createWindow',
            url: $('input[name=link]').val()
          }, function(message) {
            console.log(message);
            })
    });
});

chrome.runtime.onMessage.addListener(
  function(request, sender, sendResponse) { 
    alert('a');
    console.log(sender.tab ?
                "from a content script:" + sender.tab.url :
                "from the extension");
    if (request.greeting == "hello")
      sendResponse({farewell: "goodbye"});
});

eventPage.js

chrome.runtime.onMessage.addListener(function(request) {
    if (request && request.action === 'createWindow' && request.url) {
        chrome.windows.create(
            {
                url: request.url,
                focused: true,
                incognito: true,
                type: "panel"
            }, function (newWindow) {
                chrome.tabs.executeScript(newWindow.tabs[0].id, {
                    file: "jquery.min.js"
                }, function() {
                    chrome.tabs.executeScript(newWindow.tabs[0].id, {
                        file: "htmlselection.js"
                    });
                });
                chrome.tabs.insertCSS(newWindow.tabs[0].id, {file: "htmlselection.css"});
        });
    } else {
        chrome.tabs.query({active: true, currentWindow: true}, function(tabs){
            console.log(chrome.tabs);
            chrome.tabs.sendMessage(tabs[0].id, {action: "SendIt"}, function(response) {});  
        });
    }
});

htmlselection.js(注入在弹出窗口/面板/窗口中)

该文件用于在浏览器扩展的弹出窗口、面板或窗口中注入,与HTML选择相关。
[...]
//After a click within the popup/panel/window
chrome.runtime.sendMessage({ text: 'test' });
[...]

谢谢您的帮助。
2个回答

2

更新

如果你想在chrome.runtime.onMessage中发送消息,只需使用回调函数sendResponse或使用sender.tab.id作为tabId来发送消息。

此外,你的代码还有其他问题:

  1. Since you are use Programming injection to inject script, you should declare them in "web_accessible_resources" in manifest.json

    "web_accessible_resources": [
        "htmlselection.js",
        "jquery.min.js",
        "htmlselection.css"
    ]
    
  2. In your contentscript.js, just remove message part, since you didn't receive anything in this script.

  3. For eventpage.js, use sendResponse instead of tab.query.

    else {
        console.log("2");
        sendResponse({ action: "SendIt" });
    }
    

上一页

请查看消息传递,您可以使用以下代码片段从后台页面发送消息:

chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
  chrome.tabs.sendMessage(tabs[0].id, {greeting: "hello"}, function(response) {
    console.log(response.farewell);
  });
});

请问您能提供更多信息吗?比如这段代码应该在哪里调用? - Kaymaz
@Kaymaz,这段代码片段应该在后台页面中调用。 - Haibara Ai
似乎“tabs”仅包含当前的弹出窗口/面板。我添加了一个“chrome.runtime.addListener”,但它没有接收到任何消息。我更新了我的问题。 - Kaymaz
使用 sendResponse,我正在回复我的弹出窗口,而不是我的主页面(contentScript)。 所以我这样做: MainPage --> eventPage <--> popup - Kaymaz
@Kaymaz,那创建新窗口时设置focused: false怎么样?或者在从主页接收消息时将tabId保存为本地缓存,并在发送回消息时重用它。 - Haibara Ai

-2

修正后的代码片段:

chrome.tabs.query({active: true, currentWindow: false}, function(tabs) {
  chrome.tabs.sendMessage(tabs[0].id, {greeting: "hello"}, function(response) {
    console.log(response.farewell);
  });
});

currentWindow:false设置为false,它就可以工作了。


这个答案不正确,currentWindow: false会返回任何非当前活动窗口,请看我的回答。 - Haibara Ai

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接