簡體   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