繁体   English   中英

Chrome 扩展上下文菜单 sendResponse 在某些页面上不起作用

[英]Chrome extension contextmenus sendResponse doesn't work on some pages

我想构建一个扩展,能够在阅读一些英文文章时获取用户选择的英文单词,同时获取整个句子。

↓ 这是我的 background.js 文件。 我使用 getSelection function 向 content.js 发送消息以请求包含选择信息的响应。

//background.js

chrome.runtime.onInstalled.addListener((tableId, changeInfo, tab) => {
    chrome.contextMenus.create({
        id: 'addWords',
        title: "Send \"%s\" to background",
        contexts: ['all']
    })

    function getSelection(info, tab) {
        if (info.menuItemId === "addWords") {
            chrome.tabs.sendMessage(tab.id, {action: "getSelection"}, (response) => {
                console.log(response);
            });
        }
    }

    chrome.contextMenus.onClicked.addListener(getSelection);
});

↓ 这是我的 content.js 文件。 我使用onMessage 来响应后台的请求。

//content.js
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
    if(request.action === "getSelection"){
        let selection = window.getSelection();
        if(selection.toString() !== ""){
            let arr = selection.anchorNode.data.split(".");
            let word = selection.toString();
            let sentence = arr.find(str => str.includes(word))
            alert(word);
            sendResponse({word: word, sentence: sentence});
        }
    }
})

↓ 这是我的 manifest.json 文件

{
    "manifest_version": 3,
    "name": "Words Repeater",
    "description": "Repeat words what you want to memorize",
    "version": "1.0.0",
    "permissions": ["contextMenus", "activeTab", "tabs"],
    "action": {
        "default_popup": "popup.html"
    },
    "background": {
        "service_worker": "./js/background.js"
    },
    "content_scripts": [
        {
          "matches": ["http://*/*", "https://*/*"],
          "js": ["./js/content.js"]
        }
    ]
}

该扩展程序最初工作正常,但在更改网站后失败,我收到错误消息“未检查的运行时。lastError:无法建立连接。接收端不存在。”

如何使上下文菜单在每个选项卡上正确运行? 真的很感谢你的帮助!

  • 您的 onClicked 事件侦听器错位在 onInstalled 侦听器中,因此它只会在安装/更新后立即工作不到一分钟,直到后台脚本自动终止,然后它将被忽略,就像它不存在一样。 每次后台脚本在上下文菜单单击等事件上启动时,将其移到外面以正确地重新注册它。

  • 安装/更新扩展时,其新内容脚本不会自动注入到 Chrome/ium 中当前打开的选项卡中,因此您必须自己明确地执行此操作,如此处所示,但在以下情况下有更好的选择你的,只有在用户调用扩展后才需要访问页面:通过 executeScriptactiveTab权限串联的编程注入。

    • 从 manifest.json 中删除content_scripts - 现在您的扩展不需要广泛的主机权限,即 web 商店中不会出现安装警告。

    • 从“权限”中删除“选项卡”- 没有必要,现在不会有关于观察浏览器历史记录的警告。

    • 将“脚本”添加到“权限”。

  • 考虑将上下文限制为"selection"以仅在选择文本时显示它,而不是在错误的上下文中显示,例如工具栏中扩展图标的内置菜单。

  • chrome.runtime.onInstalled 的参数错误地从 chrome.tabs.onUpdated 侦听器复制而来,但由于它们未被使用,您可以删除它们。

chrome.runtime.onInstalled.addListener(() => {
  chrome.contextMenus.create({
    id: 'addWords',
    title: 'Send "%s" to background',
    contexts: ['selection'],
  });
});

chrome.contextMenus.onClicked.addListener(async (info, tab) => {
  if (info.menuItemId === 'addWords') {
    let word = info.selectionText.trim();
    let sentence;
    try {
      [{ result: sentence }] = await chrome.scripting.executeScript({
        target: {
          tabId: tab.id,
          frameIds: [info.frameId],
        },
        func: () => {
          const selection = window.getSelection();
          const arr = selection.anchorNode.data.split('.');
          const word = selection.toString();
          const sentence = arr.find(str => str.includes(word));
          return sentence;
        },
      });
    } catch (e) {} // invoked on a page that doesn't allow injection
    console.log(word, sentence); // this prints in background console
  }
});

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM