Dan*_*anF 4 firefox-addon content-script firefox-addon-webextensions
我正在开发浏览器扩展/附加组件。我们可以在Chrome浏览器中运行它,因此我正在尝试使其在Firefox中运行。
我已将加载项加载到Firefox Developer Edition 49.0a2(2016-07-25)中。
我的扩展程序涉及一个content_script设置为run_at: document_start,因此它可以在运行其他页面脚本之前注入一个脚本标记,从而可以使一个对象可全局用于网站。
在Chrome浏览器中,这似乎工作正常,但在Firefox中,这已证明是一种竞争状况,其他时间大多数页面优先加载页面资源。
是否有一种策略来加载内容脚本,使其可以在运行任何其他页面脚本之前注入并加载脚本?
当我添加日志时,我可以很好地隔离正在发生的事情。在此示例中,内容脚本为:
// inject in-page script
console.log('STEP 1, this always happens first')
var scriptTag = document.createElement('script')
scriptTag.src = chrome.extension.getURL('scripts/inpage.js')
scriptTag.onload = function () { this.parentNode.removeChild(this) }
var container = document.head || document.documentElement
// append as first child
container.insertBefore(scriptTag, container.children[0])
Run Code Online (Sandbox Code Playgroud)
现在,如果文件scripts/inpage.js只是运行日志,例如
console.log('STEP 2, this should always run second')
Run Code Online (Sandbox Code Playgroud)
我访问了一个带有如下脚本的页面:
console.log('Step 3, the page itself, should run last')
Run Code Online (Sandbox Code Playgroud)
实际上,步骤2和步骤3以不确定的顺序运行。
非常感谢!
如果您敢自己尝试,我在特殊分支的公共存储库中有脚本的Firefox兼容版本:https : //github.com/MetaMask/metamask-plugin/tree/FirefoxCompatibility
具有外部源(<script src>)的动态插入脚本不会阻止脚本的执行,因此无法保证脚本会被加载。如果您的扩展程序在Chrome浏览器中可以正常运行,那纯粹是靠运气。
如果您真的想在其余脚本之前运行某些脚本,则必须内联运行它:
var actualCode = `
// Content of scripts/inpage.js here
`;
var s = document.createElement('script');
s.textContent = actualCode;
(document.head || document.documentElement).appendChild(s);
s.remove();
Run Code Online (Sandbox Code Playgroud)
理想情况下,您的构建脚本应读取scripts/inpage.js,将其序列化为字符串并将其放入actualCode变量中。但是,如果inpage.js仅是几行代码,则可以使用上面的代码。
请注意,除非绝对必要,否则您不应在网页中插入代码。原因是页面的执行环境不受信任。如果在处注入document_start,则可以保存以后使用的函数和(原型)方法(在闭包中),但是需要非常仔细的编码。
如果您的内容脚本不是由构建脚本生成的,并且您仍然希望将脚本分开,那么也可以使用同步XMLHttpRequest来获取脚本。出于性能原因,不赞成使用同步XHR,因此使用此风险自担。扩展代码通常与扩展捆绑在一起,因此使用sync xhr的风险应较低:
// Note: do not use synchronous XHR in production!
var x = new XMLHttpRequest();
x.open('GET', chrome.runtime.getURL('scripts/inpage.js'), false);
x.send();
var actualCode = x.responseText;
var s = document.createElement('script');
s.textContent = actualCode;
(document.head || document.documentElement).appendChild(s);
s.remove();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
649 次 |
| 最近记录: |