首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >只在网页中注入一次内容脚本

只在网页中注入一次内容脚本
EN

Stack Overflow用户
提问于 2022-11-30 08:33:48
回答 1查看 60关注 0票数 0

我正在尝试在上下文菜单上注入内容脚本,点击扩展清单版本3,我需要检查它是否已经注入。如果没有注入内容脚本,则注入内容脚本。这个条件必须得到满足。有人能帮我吗?

我们可以用

代码语言:javascript
代码运行次数:0
运行
复制
ALREADY_INJECTED_FLAG

但是只能在内容脚本中检查这一点,因此这种方法不能像预期的那样工作。

payload.js(内容脚本)

代码语言:javascript
代码运行次数:0
运行
复制
function extract() {
    
    htmlInnerText = document.documentElement.innerText;
    url_exp = /[-a-zA-Z0-9@:%_\+.~#?&//=]{2,256}\.[a-z]{2,4}\b(\/[-a-zA-Z0-9@:%_\+.~#?&//=]*)?/gi;
    regex =  new RegExp(url_exp)
    list_url = htmlInnerText.match(url_exp)

    ip_exp = /\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b/;
    list_ip = htmlInnerText.match(ip_exp)

    hash_exp = /\b[A-Fa-f0-9]{32}\b|\b[A-Fa-f0-9]{40}\b|\b[A-Fa-f0-9]{64}\b/g
    list_hash = htmlInnerText.match(hash_exp)

    chrome.storage.local.set({ list_url: list_url, list_ip: list_ip, list_hash: list_hash });

}

chrome.runtime.sendMessage( extract());

background.js

代码语言:javascript
代码运行次数:0
运行
复制
genericOnClick = async () => {

    // Inject the payload.js script into the current tab after the backdround has loaded
    chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) {
        chrome.scripting.executeScript({
            target: { tabId: tabs[0].id },
            files: ["payload.js"]
        },() => chrome.runtime.lastError);
    });
    

    // Listen to messages from the payload.js script and create output.
    chrome.runtime.onMessage.addListener(async (message) => {
    
        chrome.storage.local.get("list_url", function (data) {
            if (typeof data.list_url != "undefined") {
                urls = data.list_url
            }
        });
        chrome.storage.local.get("list_ip", function (data) {
            if (typeof data.list_ip != "undefined") {
                ips = data.list_ip
            }
        });
        chrome.storage.local.get("list_hash", function (data) {
            if (typeof data.list_hash != "undefined") {
                hashes = data.list_hash;
            }
        });

        
        if ( hashes.length>0 || urls.length>0 || ips.length>0 ){
            chrome.windows.create({url: "output.html", type: "popup", height:1000, width:1000});
        }
    });
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-11-30 13:35:09

在我的第一个上下文菜单上单击

,我只得到一次输出html。第二次单击时,我同样两次获得输出html。

这种行为是由两个因素综合造成的。

第一因素

你打电话给chrome.runtime.onMessage.addListener() You genericOnClick()。因此,每次用户单击上下文菜单项时,代码都会添加一个新的onMessage侦听器。如果将命名函数传递给chrome.runtime.onMessage.addListener(),则不会出现问题,因为命名函数只能为事件注册一次。

代码语言:javascript
代码运行次数:0
运行
复制
function on_message(message, sender, sendResponse) {
    console.log("bg.on_message");
    sendResponse("from bg");
}

chrome.runtime.onMessage.addListener(on_message);

第二因素

但是,您没有将命名函数注册为onMessage处理程序。你在注册一个匿名函数。每次单击上下文菜单项都会创建和注册一个新的匿名函数。因此,在单击上下文菜单项后,将有N个不同的onMessage处理程序,每个处理程序都将打开一个新窗口。

解决方案

  1. 将onMessage处理程序定义为一个命名函数,如上面所示.
  2. 在函数之外调用chrome.runtime.onMessage.addListener() .

你不必同时做1和2,两者都能解决你的问题。但我建议两种方法都做,因为它更干净。

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

https://stackoverflow.com/questions/74624848

复制
相关文章

相似问题

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