[英]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 中当前打开的选项卡中,因此您必须自己明确地执行此操作,如此处所示,但在以下情况下有更好的选择你的,只有在用户调用扩展后才需要访问页面:通过 executeScript与activeTab
权限串联的编程注入。
从 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.