首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Chrome扩展::尝试理解chrome.runtime.sendmessage到chrome.runtime.onMessage的语法

问Chrome扩展::尝试理解chrome.runtime.sendmessage到chrome.runtime.onMessage的语法
EN

Stack Overflow用户
提问于 2021-10-13 00:03:24
回答 1查看 805关注 0票数 1

对于chrome.runtime.sendmessage如何将数据从Content.js文件发送到chrome.runtime.onMessage Background.js文件的语法,我有一些问题。我试图注入一个脚本来查看网页指标,并在导航到新页面时在Chrome扩展弹出中显示它们。我无法看到从content.js脚本发送到background.js脚本的变量。我不需要在会话之间缓存数据,只希望我的脚本运行在用户所在的当前选项卡中。

我的Content.js脚本应该与位于Manifest.js中的"run_at": "document_idle"一起执行。

Background.js中的Content.js Run> setBadgeAction显示图标上的度量>用户可以在扩展弹出中打开报表

Background.js:

代码语言:javascript
复制
chrome.runtime.onMessage.addListener((request, sender, sendResponse){
    chrome.browserAction.setBadgeText({
                        text: request.apple,
                        tabId: sender.tab.id
                    });
                    chrome.browserAction.setPopup({
                        tabId: sender.tab.id,
                        popup: "popup.html"
                    });
               });

content.js:

代码语言:javascript
复制
function webFunction(){

var apple = 0;
var orange = 3;
var kiwi = 5;
var banana = 13;

chrome.runtime.sendMessage({
    apple: apple,
    orange: orange,
    kiwi: kiwi,
    banana: banana,    
            });
}

popup.js

代码语言:javascript
复制
chrome.tabs.query({
        active: true,
        currentWindow: true
    });
chrome.runtime.onMessage.addListener((request,sender) =>{
            
document.getElementById("appleTag").innerHTML = request.apple;
document.getElementById("orangeTag").innerHTML = request.orange;
document.getElementById("kiwiTag").innerHTML = request.kiwi;
document.getElementById("bananaTag").innerHTML = request.banana;
});

popup.html

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="popup.css">
<script src="popup.js"></script>
</head>
<body>

<p id ="appleTag">Apple Score</p>
<p id ="orangeTag">Orange Score</p>
<p id ="kiwiTag">Kiwi Score</p>
<p id ="bananaTag">Banana Score</p>
</body>
</html>

manifest.js

代码语言:javascript
复制
{
  "name": "",
  "description": "",
  "version": "1.0",
  "manifest_version": 3,
  "action":{
        "default_popup": "popup.html",
        "default_icon": {
            "16": "/images/16.png",
            "32": "/images/32.png",
            "48": "/images/48.png",
            "128": "/images/128.png"
        }
    },
  "content_scripts": [
        {
            "matches": [
                "*://*/*"
            ],
            "run_at": "document_idle",
            "js": [
                "content.js"
            ]
        }
      ],
  "options_page": "popup.html", 
  "background": {
    "service_worker": "background.js"
},
// Permissions for the Extension.    
  "permissions": [
      "storage", 
    "activeTab" 
],
"icons": {
      "16": "/images/16.png",
      "32": "/images/32.png",
      "48": "/images/48.png",
      "128": "/images/128.png"
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-10-13 03:55:52

有几个小问题,我首先要谈一谈:

background.js:

  • chrome.runtime.onMessage.addListener缺少=>或function,这取决于您的风格
  • 清单3中的chrome.browserAction已重命名为chrome.action
  • 设置徽章文本时,text属性必须是string类型
  • chrome.action.setPopup不是必需的,因为在清单(action.default_popup)中已经指定了弹出窗口;如果/当您希望在运行时动态地将弹出模板更改为不同的模板时,请使用setPopup if/。

content.js

  • 函数webFunction永远不会被调用,因此sendMessage也不会被调用。

还有另一个概念问题,涉及扩展部分之间的数据流,以及不同部分何时处于活动/非活动状态并能够接收消息。该流程的目的似乎是将数据从内容脚本发送到后台,并或多或少地同时弹出。

后台服务工作人员可以用于接收来自内容的消息,然后更新徽章文本,并且在解决了上面列出的语法问题之后,它将正确工作。

当用户实际单击扩展图标并打开弹出窗口时,弹出窗口是活动的。弹出失去焦点后,它将得到回收和重新加载下一次用户单击扩展图标。当用户集中在选项卡上并运行内容脚本时,弹出窗口不能同时打开,因此无法接收消息。

为了将数据传递给弹出窗口,您需要一些中介从内容中接收数据,然后在弹出窗口加载并准备接收数据时将其提供给弹出窗口。在清单V2中,将背景用于此目的(可能)是合理的,因为它不打算长期存储,但是对于MV3,后台服务工作人员的寿命很短,过一段时间它将变得不活动。由于这个原因,它将不能作为一个可靠的中介机构来保存数据,即使是暂时的。您可以找到一些关于这个主题的官方讨论,这里。

为了达到预期的行为,我建议使用存储API。这将允许捕获内容脚本中的数据,并在弹出窗口准备加载时恢复相同的数据。这可能已经是目的了,因为存储包含在所需的清单权限中。您可能需要考虑使用一些查找键从每个特定选项卡的存储中获取数据,如果在这方面计数会有所不同,那么在选项卡/窗口/浏览器关闭时清除存储数据。

下面是一个经过编辑的版本,其中包含建议的更改

content.js

代码语言:javascript
复制
// removed webFunction declaration
 
var apple = 0;
var orange = 3;
var kiwi = 5;
var banana = 13;
var counts = {apple, orange, kiwi, banana}

chrome.storage.local.set(counts);   // persist data
chrome.runtime.sendMessage(counts); // send to background

background.js

代码语言:javascript
复制
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
    if (request.apple !== undefined) // null check before setting badge
        chrome.action.setBadgeText({
            text: request.apple.toString(),
            tabId: sender.tab.id
        });
});

popup.js

代码语言:javascript
复制
// get counts from storage; null means "get everything"
chrome.storage.local.get(null, request => {
    document.getElementById("appleTag").innerHTML = request.apple;
    document.getElementById("orangeTag").innerHTML = request.orange;
    document.getElementById("kiwiTag").innerHTML = request.kiwi;
    document.getElementById("bananaTag").innerHTML = request.banana;
});

在popup.html中,我会在<p>标记之后将<script src="popup.js"></script>移动到正文的末尾,因为它通过id查找元素,以确保这些id的存在。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69548229

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档