浏览器扩展:如何将 javascript 代码注入页面而不会发生冲突?
Posted
技术标签:
【中文标题】浏览器扩展:如何将 javascript 代码注入页面而不会发生冲突?【英文标题】:Browser extensions: how can injecting javascript code into a page work without conflicts? 【发布时间】:2012-07-15 14:49:26 【问题描述】:我已经开始开发浏览器扩展。我注意到一个常见的概念是扩展可以将 JS 代码注入到当前浏览器选项卡中。
我有点困惑,为什么这不会经常引起问题。
我的意思是,如果我将版本 x 的 JQuery(通过我的浏览器扩展)注入到已经包含版本 y 的 JQuery 的页面中,事情怎么可能仍然有效? $()
函数不会有冲突吗?
事情怎么可能这么顺利?开发人员是否应该采用任何特定技术来确保不会发生此类冲突,或者浏览器会处理所有事情?
【问题讨论】:
【参考方案1】:虽然noConflict()
可能大部分时间都适用于 jQuery,但它对于扩展来说仍然是个坏主意,并且不适用于大多数其他库或实用程序。
明智的做法是根本不注入代码(有一个例外1)。该扩展可以包含您需要的任何库,这样做有很多好处:
不可能与页面的javascript发生冲突。
不依赖页面的JS,更改不另行通知,您的扩展将不那么频繁地崩溃。
当您注入一个库时,它必须从某个外部服务器获取。这会减慢您的扩展程序并使其容易受到您无法控制的崩溃的影响。
当您在扩展中包含该库时,它是:(a) 始终存在,(b) 始终是已知良好的版本,以及 (c) 几乎立即从本地计算机加载,而不是从某个遥远的服务器加载。
即使页面的 javascript 被禁用,您的扩展程序也可以运行。
您的扩展程序可以同时利用库和扩展程序 API。
使用扩展很容易合并像 jQuery 这样的库。例如,使用 Chrome:
-
将库文件复制到您的扩展文件夹。
将库添加到manifest.json
文件。
包含 jQuery 的简单清单可以是:
"content_scripts": [
"exclude_globs": [ ],
"include_globs": [ "*" ],
"js": [ "jquery.min.js", "myJS.js" ],
"matches": [ "http://***.com/*"
]
],
"description": "Hello world with jQuery",
"name": "Hello world with jQuery",
"version": "1"
Firefox 和其他浏览器的机制类似。
1 一个例外?对于扩展,当且仅当满足所有这些条件时才注入代码:
-
该扩展程序仅适用于一个特定站点。
您绝对必须使用目标页面创建的某些对象/函数。
在扩展程序中轻松复制功能太复杂了。
您不介意为网站设计的每一个细微变化都重写或调整您的扩展程序。
您可以确保所有用户都启用了网站的 javascript。
您可以确定为您的图书馆提供服务的网站运行速度相当快,而且不会经常离线。
【讨论】:
我认为 content_scripts 总是被注入 - 看看 Chrome 文档:code.google.com/chrome/extensions/content_scripts.html,在第一段“Manifest”。 尽管该页面误用了“注入”一词,但它们并不像其他任何人使用该术语(在目标页面范围内运行的代码)那样表示“注入”。事实上,Chrome 文档在其他地方描述了实际行为,包括稍后在同一页面上。见Execution environment。 ... ...“注入”的常见和正确用法是当您的脚本或扩展创建<script>
节点(或unsafeWindow
的某些用法)时。
你说得对——在那个段落中,他们甚至说“例如,内容脚本可以包含 JQuery v1,页面可以包含 JQuery v2,它们不会相互冲突。” - 正是我所要求的。谢谢。
基本上我对他们使用“注入”一词的方式感到困惑
是的,该页面的使用令人困惑且不标准。这仅适用于 Chrome 吗?【参考方案2】:
jQuery 有一个 noConflict()
函数,可用于将 jQuery 与使用 $
命名空间的其他任何东西(例如 jQuery 的不同实例)隔离开来。
避免前向命名空间污染的更通用方法是考虑在闭包中执行 JavaScript。
(function ()
// Your Code Here
)();
这将阻止闭包范围内的任何内容在您自己的代码之外可用。
【讨论】:
【参考方案3】:此问题的常见解决方案是使用 jQuery.noConflict() 将您的 jQuery 别名为不同的变量,确保它不会与页面的 $
冲突。
【讨论】:
另一个很多注入使用的好习惯是检查并查看 jQuery 在注入之前是否已经存在。如果做不到这一点,是的,noConflict 有效。 (每当我必须做那种事情时,我通常使用$$
,但如果你想要超级安全,你可能想使用YourPlugin$
。这听起来可能很痛苦,打字,但是如果你使用模块模式(你可能应该使用它)你只需要在每个文件中输入一次。以上是关于浏览器扩展:如何将 javascript 代码注入页面而不会发生冲突?的主要内容,如果未能解决你的问题,请参考以下文章
javascript 当您单击浏览器操作图标时,只需极少的Chrome扩展即可将JS文件注入给定页面。然后脚本插入一个n
javascript 当您单击浏览器操作图标时,只需极少的Chrome扩展即可将JS文件注入给定页面。然后脚本插入一个n
Selenium:如何在加载/执行页面的任何其他脚本之前将 Javascript 注入/执行到页面中?