我正在为Firefox浏览器编写小型WebExtention。事实证明,对于来自 manifest.json 与来自runAt
方法的内容脚本,Firefox处理browser.tabs.executeScript
属性的方式不同。
内容的script.js :
console.log('content script fired!');
后台脚本 settings-script.js :
function handleUpdated(tabId, changeInfo, tabInfo) {
var pageVar = "console.log('executeScript fired!');
var executing = browser.tabs.executeScript(tabId, {
code: pageVar,
runAt: "document_start"
});
}
browser.tabs.onCreated.addListener(handleUpdated);
browser.tabs.onUpdated.addListener(handleUpdated);
测试page.html中:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>test my behaviour</title>
</head>
<body>
<script type="text/javascript">
console.log('start very first page script');
</script>
</body>
</html>
的manifest.json :
"permissions": [
"activeTab",
"storage",
"tabs",
"http://*/*",
"https://*/*",
"file://*/*"
],
"background": {
"scripts": ["background/settings-script.js"]
},
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["content-script.js"],
"run_at": "document_start"
}
],
控制台输出如下所示:
'content script fired!'
'start very first page script'
'executeScript fired!'
那么,当我以runAt
以编程方式注入时,为什么Firefox会忽略我的document_idle
属性并继续在tabs.executeScript()
上执行脚本?
有没有我错过的东西?
答案 0 :(得分:1)
那么,为什么当我用编程方式用tabs.executeScript()注入时,Firefox会忽略我的runAt属性并继续在document_idle上执行脚本?
没有。现在为时已晚 - 您正在与该页面竞争。
tabs.executeScript
会将runAt
作为最早运行脚本的机会。但是当您的executeScript
实际运行时,页面已经完全加载。
考虑一下:使用manifest.json
中定义的脚本,Chrome会提前知道某些脚本必须在页面加载之前。
另一方面,tabs.onCreated
/ tabs.onUpdated
在创建/更新开始后的某个时刻触发。有一个自然的处理延迟,而页面继续加载 - 它不是一个阻止事件,直到所有扩展决定做什么。当您调用executeScript
API时,Chrome还需要一些时间来调整其内部机制。
你的琐碎页面已经结束了。对于缓慢加载的页面,您可能会看到差异,但不会显示您作为测试显示的页面。
正确的解决方案,在运行时决定哪些脚本提前并不存在。理论上,chrome.declarativeContent.RequestContentScript
应该允许这样做 - 但即使在稳定的Chrome版本中也不支持它,当然也不支持Firefox。
如果您需要在document_start
脚本中实现某些条件逻辑,那么它非常困难 - 您无法异步执行任何操作,因此chrome.storage
和Messaging无法提供帮助。< / p>