【问题标题】:Loading external javascript in google chrome extension在谷歌浏览器扩展中加载外部 javascript
【发布时间】:2011-12-08 13:44:08
【问题描述】:

我正在编写一个谷歌浏览器扩展来操作当前页面(基本上是添加一个按钮)。

在我的内容脚本中,我想加载 Facebook Graph API:

$fbDiv = $(document.createElement('div')).attr('id', 'fb-root');
$fbScript = $(document.createElement('script')).attr('src', 'https://connect.facebook.net/en_US/all.js');
$(body).append($fbDiv);
$(body).append($fbScript);

console.log("fbScript: " + typeof $fbScript.get(0));
console.log("fbScript parent: " + typeof $fbScript.parent().get(0));
console.log("find through body: " + typeof $(body).find($fbScript.get(0)).get(0));

但是,脚本似乎没有添加到body。这是控制台日志:

fbScript: object
fbScript parent: undefined
find through body: undefined

关于我做错了什么有什么想法吗?

【问题讨论】:

  • 有什么原因不能将 Facebook JS 作为内容脚本之一?
  • 我试过了,但我什至无法在扩展窗口中加载脚本。它出现了这个错误:无法从'/Users/.../extentionfolder/'加载扩展。无法为内容脚本加载 javascript 'connect.facebook.net/en_US/all.js'。
  • 那是因为您提供的是外部参考,但 Chrome 希望脚本是本地的。我对 Facebook Graph API 不太熟悉;使用扩展程序保存本地副本的可行性如何?
  • 检查我在 chrome 扩展中使用 aws-sdk 的答案stackoverflow.com/questions/57893562/…

标签: javascript google-chrome facebook-graph-api google-chrome-extension


【解决方案1】:

问题在于内容脚本中的 JavaScript 在其自己的沙盒环境中运行,并且只能访问以两种方式之一加载的其他 JavaScript:

通过manifest

{
  "name": "My extension",
  ...
  "content_scripts": [
    {
      "js": ["https://connect.facebook.net/en_US/all.js"]
    }
  ],
  ...
}

或者使用Programmatic injection:

/* in background.html */
chrome.browserAction.onClicked.addListener(function(tab) {
    chrome.tabs.executeScript(null,
                       {file:"https://connect.facebook.net/en_US/all.js"});
});

确保更新您的清单权限:

/* in manifest.json */
"permissions": [
    "tabs", "https://connect.facebook.net"
 ], 

附加脚本标记实际上会在包含页面的上下文中评估 JavaScript,在您的 JavaScript 有权访问的 JavaScript 沙箱之外。

另外,由于 FB 脚本要求“fb-root”在 DOM 中,您可能需要使用编程方法,以便您可以先使用元素更新 DOM,然后 pass a message 返回背景页面加载 Facebook 脚本,以便内容脚本中加载的 JavaScript 可以访问它。

【讨论】:

【解决方案2】:

Google Chrome 扩展程序不再允许直接注入外部代码,但是您仍然可以通过 Ajax 调用下载代码并将其提供给注入器,就像它是一个代码块一样。

chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
    $.get("http://127.0.0.1:8000/static/plugin/somesite.js", function(result) {
        chrome.tabs.executeScript(tabs[0].id, {code: result});
    }, "text");
});

来源:https://stackoverflow.com/a/36645710/720665

【讨论】:

    【解决方案3】:

    如果您想将其作为内容脚本加载:

    fetch('https://example.com/content.js')
      .then(resp => resp.text())
      .then(eval)
      .catch(console.error)
    

    如果您想将其加载为后台脚本。 以https://example.com/bg.js 为例。

    1. 将远程js脚本添加到后台页面文件中,这里命名为background.html
    <!DOCTYPE html>
    <html>
    <head>
      <script src="https://example.com/bg.js"></script>
    </head>
    <body>
    <div>Empty content</div>
    </body>
    </html>
    
    1. https://example.com 添加到 manifest.json 的 content_security_policy:
    "background": {
      "page": "background.html"
    },
    "content_security_policy": "script-src 'self' https://example.com ; object-src 'self'",
    

    要求:

    1. 远程 js 脚本必须通过 https 而不是 http 提供。
    2. 您应该在背景部分指定一个页面而不是脚本数组

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-04-10
      • 1970-01-01
      • 2015-04-17
      • 2014-07-24
      • 2013-01-25
      相关资源
      最近更新 更多