You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Chrome扩展:如何仅在右键菜单点击时触发onMessage监听器

Chrome扩展监听器误触发问题:仅在右键菜单点击时调用onMessage监听器

我正在开发一款Chrome扩展,通过右键菜单点击注入内容脚本,此功能正常运行。但目前遇到问题:每当打开新标签页时,chrome.runtime.onMessage.addListener会在未点击右键菜单的情况下被触发,请问如何让该监听器仅在右键菜单点击时被调用?


现有代码

background.js

on_message = async(message, sender, sendResponse) => {
    console.log("bg.on_message");
    sendResponse("from bg");

    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){
        hash_report = await createHashReport(hashes)
        hash_table = await createHashTable(hash_report)
        chrome.storage.local.set({
            "scanHash": true,
            "hash_table": hash_table
          }, () => {});
    }
    if (ips){
        ip_report = await createIpReport(ips)
        ip_table = await createIpTable(ip_report)
        chrome.storage.local.set({
            "scanIp": true,
            "ip_table": ip_table
          }, () => {});
    }
    if (urls){
        url_report = await createUrlReport(urls)
        url_table = await createUrlTable(url_report)
        chrome.storage.local.set({
            "scanUrl": true,
            "url_table": url_table
          }, () => {});
    }
    if ( hashes.length>0 || urls.length>0 || ips.length>0 ){
        chrome.windows.create({url: "output.html", type: "popup", height:1000, width:1000});
    }
}

chrome.runtime.onMessage.addListener(on_message);

genericOnClick = async () => {
    chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) {
        chrome.scripting.executeScript({
            target: { tabId: tabs[0].id },
            files: ["payload.js"]
        },() => chrome.runtime.lastError);
    });
}

payload.js

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: removeEmails(removeDuplicates(list_url)), list_ip: removeDuplicates(list_ip), list_hash: removeDuplicates(list_hash) });
}

chrome.runtime.sendMessage( extract())

解决方法

1. 给消息添加唯一标识,过滤非右键触发的请求

当前监听器会响应所有chrome.runtime.sendMessage请求,包括其他扩展或页面脚本的消息。我们可以给右键菜单触发的消息添加专属标识,仅处理带该标识的请求:

修改payload.js,发送带标识的消息:

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: removeEmails(removeDuplicates(list_url)), 
        list_ip: removeDuplicates(list_ip), 
        list_hash: removeDuplicates(list_hash) 
    });

    // 发送带专属标识的消息
    chrome.runtime.sendMessage({ action: "right_click_scan" });
}

// 正确执行逻辑:先提取再发消息
extract();

修改background.js的监听器,先校验标识:

on_message = async(message, sender, sendResponse) => {
    // 仅处理右键菜单触发的消息
    if (message?.action !== "right_click_scan") return;

    console.log("bg.on_message");
    sendResponse("from bg");
    // 原处理逻辑保持不变
}

2. 修复payload.js的消息发送错误

原代码中chrome.runtime.sendMessage(extract())会直接执行extract并把其返回值(undefined)作为消息发送,属于写法错误,改成先执行extract再发送消息即可。

3. 可选:限制消息来源为当前扩展的内容脚本

通过sender参数进一步校验消息来源,确保只有当前扩展注入的内容脚本触发的请求才会被处理:

on_message = async(message, sender, sendResponse) => {
    // 校验标识+来源
    if (message?.action !== "right_click_scan" || sender.id !== chrome.runtime.id) return;

    // 原处理逻辑保持不变
}

内容的提问来源于stack exchange,提问作者tonia j sebastian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 21:01:40