我试图将JS代码注入网站,代码在其所有网页上执行。我发现这可以使用chrome内容脚本完成。因此,我做了以下事情:
我已创建" contentscript.js"。
var x = []
s.src = 'AN EXTERNAL JS FILE';
(document.getElementsByTagName('head')[0] || document.body).appendChild(s);
我已经创建了" manifest.json"。
{
"name": "Sample",
"version": "1.0",
"manifest_version": 2,
"permissions": [
"tabs",
"*://*/*"
],
"icons": { "128":"logo.png" },
"content_scripts": [{
"js": ["contentscript.js"],
"matches": ["<all_urls>"]
}]
}
两个文件都存在于同一个文件夹中。
我已将它们加载到Chrome扩展程序中。
脚本按预期执行。
我注入的脚本将外部JS文件加载到页面中,并在head标记下放置一个脚本元素。这个JS也使用我在注入的JS脚本中定义的x
变量。但它无法读懂它的问题。在控制台中,它会抛出错误,x
变量未定义。
如何以外部JS文件可访问的方式定义变量,提到我既不能访问网站也不能访问外部JS文件?
谢谢,
答案 0 :(得分:2)
内容脚本位于an isolated world。您可以在页面上下文之外定义<script>
,因此它在其中运行的脚本是不可见的。有关详细信息,请参阅this answer。
但是,通过x
标记添加脚本会将脚本放入页面的上下文中。因此,它没有看到变量。
您有3种可能的解决方案。
在页面的上下文中完全使用<script>
。因此,您需要在script = document.createElement("script");
script.textContent = 'x = [];';
(document.getElementsByTagName('head')[0] || document.body).appendChild(script);
代码中定义它:
x
让页面级脚本和内容脚本进行通信(例如,传递postMessage
)。
实现此目标的一种方法是通过custom DOM events。另一个是described in the docs(Symfony profiler/toolbar
)。最后,正如xwhyLikeThis所建议的那样,您可以将值存储在隐藏的DOM节点中。
在内容脚本上下文中加载外部脚本。这需要从后台脚本和XHR使用injecting it programmatically获取它。或者,如果您可以使用扩展名包含文件的静态版本 - 只需按照常规方式将其与内容脚本一起注入。
就个人而言,我建议2。