【问题标题】:Run javascript in an "isolated world" (chrome)在“孤立的世界”中运行 javascript (chrome)
【发布时间】:2016-03-21 16:55:15
【问题描述】:

我开发的 chrome 扩展通过 HTML 导入将 Polymer 和其他 Web 组件注入到主机页面中,而不是使用内容脚本的典型方法 - 它自动在 isolated world 中运行。

这背后的原因与两件事有关:

  1. Chrome 扩展无法注册来自content scripts 的自定义元素
  2. chrome 扩展清单不支持在隔离环境中运行的 HTML 导入,仅支持 javascript

由于这些限制,我不得不将我的组件加载到主机页面的<head> 中作为described here

我面临的明显问题是我的 javascript [在某些网站上] 与主机页面的 javascript 发生冲突,因为我用来注入我的依赖项的方法不在“孤立的世界”中运行。

到目前为止,我已经通过 gulp 任务重命名 Polymer 和我的组件以避免冲突解决了大部分问题,但不幸的是,它并不完美,需要更强大的方法。

最后是我的问题:是否可以为我的 javascript 创建一个“孤立的世界”?也许是另一个文档对象?如果没有,我可以采用什么策略来确保我的代码独立运行?

更新:

你们中的一些人建议使用我迄今为止一直在使用的 IIFE。我正在寻找一个孤立世界的答案,类似于 google chrome 如何在其下运行扩展。这主要是因为 Polymer 必须附加到全局窗口对象。

【问题讨论】:

  • 您指的是哪些冲突?只是变量名/函数冲突或更复杂的冲突?
  • 变量/函数名冲突。如果主机页面使用它自己的 Polymer 版本,则尤其如此。
  • 你不能使用页面上的聚合物吗?检查它是否已经存在,如果没有注入你的?
  • 该页面可能有不同版本的 Polymer,它们的工作方式完全不同。
  • 看起来很难,也许这有用:github.com/asvd/jailed

标签: javascript google-chrome google-chrome-extension polymer


【解决方案1】:

您可以使用a closure 限定变量(包括函数,因为它们是 javascript 中的第一类对象)。

因此,如果您使用 IIFE 注入以下代码 - 立即调用函数表达式 -

var someVar = 'this one "conflicts" with page js';
(function(){
    var someVar = 'this one does not "conflict" with page js'; //shadows someVar above
    console.log(someVar);
})();
console.log(someVar);

您会看到访问someVar 会返回不同的值。

作为注入代码的一部分,您可以通过这种方式隐藏“冲突”变量 - 例如 Polymer。

使用 CommonJS require() 之类的内容在 IIFE 中导入所需的版本,并继续从父范围访问其他任何内容。

【讨论】:

    【解决方案2】:

    为了定义:

    隔离作用域

    被广泛称为 IIFE,它是一种用于 javascript“闭包”的设计模式。

    孤立的世界

    或者“孤立的世界”,正如问题的作者 dipole 所描述的那样,在同一环境中运行但彼此不了解的 JavaScript 应用程序。

    可能的答案

    这个问题我已经回答了here

    我的建议

    虽然“孤立的世界”不是 javascript 中的“事物”,或者至少直到最近才出现,但本着提供可能解决方案的精神,请查看 Dynamic Script Loading .

    如果您不将脚本动态加载到“隔离范围”并在该范围内使用您的函数,您仍然会遇到冲突。

    【讨论】:

      【解决方案3】:

      对于它的价值,iframe 是相当孤立的 :)

      不要将 Polymer 直接添加到主机页面 <head>,而是尝试在主机页面中创建一个 <iframe>,并将 Polymer 和其他 Web 组件添加到内部 <iframe> 文档中。

      您可以动态创建 <iframe> 内容或尝试在您的扩展程序中引用 (src="") 一个 HTML 文件(不确定,SOP 可能会妨碍您)。

      (您可以使 iframe 透明并覆盖在任何您想要的位置)。

      希望这有效/有帮助。

      【讨论】:

      • 感谢您的建议,但不幸的是 iframe 对我来说不是一个可行的选择。该扩展包含许多需要与页面中的元素交互的不同组件,而不是可以独立的单个组件。
      【解决方案4】:

      只是一个建议:你可以试试 service workers。在单独的线程中运行您的 javascript 并在那里使用您自己的库。

      【讨论】:

        猜你喜欢
        • 2023-02-02
        • 1970-01-01
        • 1970-01-01
        • 2012-06-19
        • 2014-02-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多