gpt4 book ai didi

javascript - 如何防止多次注入(inject)/执行内容脚本以响应单个事件?

转载 作者:行者123 更新时间:2023-11-30 00:34:11 24 4
gpt4 key购买 nike

我正在构建一个响应上下文菜单上的点击事件的 chrome 扩展。

我的后台脚本使用 chrome.contextMenus.create api 方法调用创建上下文菜单并设置点击处理程序,如下面的代码所示:

//event.js
function onItemClick(info, tab){
// Inject the content script into the current page
chrome.tabs.executeScript(null, { file: 'content.js' });

// Perform the callback when a message is received from the content script
chrome.runtime.onMessage.addListener(function(message){
var url = "data:text/html;charset=utf8,";

function append(key, value){
var input = document.createElement('textarea');
input.setAttribute('name', key);
input.textContent = value;
form.appendChild(input);
}

var form = document.createElement('form');
form.method = 'POST';
form.action = 'http://localhost/myapp/myapp.php';
form.style.visibility = "hidden";
append('url', message.url);
append('text', message.selectedText);
url = url + encodeURIComponent(form.outerHTML);
url = url + encodeURIComponent('<script>document.forms[0].submit();</script>');
chrome.tabs.create({url: url, active: true});
});
}

var context = "selection";
var title = "Share in new tab";
var id = chrome.contextMenus.create({"title": title, "contexts": [context], "onclick": onItemClick});

上面的后台脚本以编程方式创建一个表单,该表单会自动在新选项卡中提交。这样做时,它会调用下面的“内容脚本”以从当前页面/选项卡获取一些信息。

//content.js
chrome.runtime.sendMessage({
'url': window.location.href,
'selectedText': window.getSelection().toString()
});

问题是这样的。后台脚本中的点击处理程序多次(即每次调用点击处理程序时)将“内容脚本”注入(inject)当前页面。作为这种多次注入(inject)的结果,“内容脚本”的每个注入(inject)实例都会被执行,从而导致打开多个新选项卡/页面。每次单击上下文菜单项时,打开的新选项卡数量都会增加一个,这表明问题确实是内容脚本的多次注入(inject)和执行。我怎样才能只注入(inject)一次内容脚本,或者至少确保注入(inject)脚本中只有一个“实例”将消息发送回我的后台脚本?

我曾尝试在 list 中自动注入(inject)脚本,但此后调用 chrome.tabs.executeScript 会导致无休止地创建选项卡。所以,我真的需要能够按需注入(inject)脚本,但要找到一种方法来防止多次注入(inject)或至少确保只有一次“注入(inject)”发回消息。请帮忙!

最佳答案

解决方案很容易实现:您可以在内容脚本中创建一个全局控制变量。在开始时检查它,如果不是 true 则将其设置为 true 并继续。第一个执行的内容脚本将设置变量并阻止其他人做任何事情。

顺便说一下,我看到您在另一个监听器中向 chrome.runtime.onMessage 添加了一个监听器:这不是好的做法,因为它会为同一事件和结果添加多个监听器多次执行它们。您应该改为在外部声明监听器,发送不同的消息说“做某事”或“做其他事情”。

在内容脚本中:

// Warning! Comparing to a literal to ignore a DOM element with id=messageSent
// which automatically creates an implicit global on `window`
if (window.messageSent !== true) {
window.messageSent = true;

chrome.runtime.sendMessage({
action: "submit the form",
url: window.location.href,
selectedText: window.getSelection().toString()
});
}

background.js中:

chrome.runtime.onMessage.addListener(function(message){
if (message.action == "submit the form") {
// do what you need to submit the form
var url = "data:text/html;charset=utf8,";
function append(key, value){
...
}
});

关于javascript - 如何防止多次注入(inject)/执行内容脚本以响应单个事件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27907941/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com