我正在开发Chrome扩展程序。我没有使用manifest.json
匹配所有URL的内容脚本的方式,而是通过chrome.tabs.executeScript
在用户单击扩展图标时进行调用来懒惰地注入内容脚本。
我正在尝试避免多次执行脚本。因此,我的内容脚本中包含以下代码:
if (!window.ALREADY_INJECTED_FLAG) {
window.ALREADY_INJECTED_FLAG = true
init() // <- All side effects go here
}
问题#1,这样安全到足以在chrome.tabs.executeScript
每次单击扩展程序图标时天真地调用它吗?换句话说,这是幂等的吗?
问题2,是否有类似的方法chrome.tabs.insertCSS
?
由于无法访问网页的DOM,因此似乎无法检查backgroud脚本中的内容脚本注入状态。我已经尝试过ping / pong方法来检查任何内容脚本实例是否存在。但这引入了设计ping超时的开销和复杂性。
问题#3,有没有更好的方法来让后台脚本检查内容脚本的注入状态,因此我可以防止chrome.tabs.executeScript
每次用户单击图标时都调用它?
提前致谢!
这样安全吗,足以确保
chrome.tabs.executeScript
每次单击扩展程序图标时都能天真地拨打电话?换句话说,这是幂等的吗?
有类似的方法
chrome.tabs.insertCSS
吗?
chrome.tabs.insertCSS
。但是,再次插入相同的样式表不会改变页面的外观,因为所有规则都具有相同的CSS专用性,在这种情况下,最后一个样式表具有优先权。但是,如果样式表与您的扩展紧密结合,那么您可以简单地使用executeScript注入脚本,检查它是否是第一次注入,如果是,则插入样式表(请参见下面的示例)。还有什么更好的方法可以让后台脚本检查内容脚本的注入状态,因此我可以防止
chrome.tabs.executeScript
每次用户单击图标时都调用它?
chrome.tabs.sendMessage
)发送一条消息,如果未得到答复,则假定选项卡中没有内容脚本,然后插入内容脚本。在弹出/后台脚本中:
chrome.tabs.executeScript(tabId, {
file: 'contentscript.js',
}, function(results) {
if (chrome.runtime.lastError || !results || !results.length) {
return; // Permission error, tab closed, etc.
}
if (results[0] !== true) {
// Not already inserted before, do your thing, e.g. add your CSS:
chrome.tabs.insertCSS(tabId, { file: 'yourstylesheet.css' });
}
});
contentscript.js:
// Wrapping in a function to not leak/modify variables if the script
// was already inserted before.
(function() {
if (window.hasRun === true)
return true; // Will ultimately be passed back to executeScript
window.hasRun = true;
// rest of code ...
// No return value here, so the return value is "undefined" (without quotes).
})(); // <-- Invoke function. The return value is passed back to executeScript
请注意,window.hasRun
显式检查值很重要(true
在上面的示例中),否则它可以是具有id="hasRun"
属性的DOM元素的自动创建的全局变量,请参见是否存在将元素ID设置为全局变量的规范?
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句