将Google API JavaScript客户端库加载到Chrome扩展程序中

39

我一直在尝试将Google API的JavaScript客户端库与Chrome扩展程序结合使用,但是似乎这个Chrome扩展程序有一个十分令人沮丧的问题。该脚本的链接为:

https://apis.google.com/js/client.js

下载文件很麻烦,因为这个脚本实际上会加载其他脚本。我已经尝试将其包含在清单中:

manifest.json(摘录)

"background": {
  "scripts": [
    "background.js",
    "https://apis.google.com/js/client.js?onload=callbackFunction"
  ]
},
但是这个扩展程序没有被加载。我也尝试将脚本注入到后台HTML中。 background.js(摘录)
 var body = document.getElementsByTagName('body')[0];
 var script = document.createElement('script');
 script.type = 'text/javascript';
 script.src = "https://apis.google.com/js/client.js?onload=callbackFunction";

 body.appendChild(script);

但 Chrome 调试器给了我以下信息:

拒绝加载脚本'https://apis.google.com/js/client.js',因为它违反了以下内容安全策略指令:"script-src 'self' chrome-extension-resource:"。

有什么想法,或者它们注定无法在一起吗?

编辑:请注意,如果要使用回调函数,则必须将 "?onload=myCallbackFunction" 添加到脚本 URL 中。感谢 Ilya。更多信息请参见此处

5个回答

25

到目前为止,我找到的唯一解决方案是像我所做的那样首先将脚本注入到后台HTML页面中:

background.js(摘录)

 var head = document.getElementsByTagName('head')[0];
 var script = document.createElement('script');
 script.type = 'text/javascript';
 script.src = "https://apis.google.com/js/client.js?onload=callbackFunction";
 head.appendChild(script);

然后,为了绕过安全警告,编辑清单文件(来源):

manifest.json(摘录)

"content_security_policy": "script-src 'self' https://apis.google.com; object-src 'self'"
然而,请注意,绕过安全性只适用于https链接,并且我也觉得这样有点破解的感觉...欢迎提出其他解决方案。

13

我在https://apis.google.com/js/client.js的源代码中发现了一些有趣的内容。它的含义是:

gapi.load("client",{callback:window["gapi_onload"], ......

gapi.load函数在加载网页时立即调用client.js。当gapi.client加载后,似乎会回调window.gapi_onload函数。

作为概念验证,我构建了这个plunker:http://plnkr.co/edit/TGvzI9SMKwGM6KnFSs7U

gapi.authgapi.client都已成功打印到控制台。


回到Chrome扩展程序。

我将以下内容放在manifest.json的背景部分中:

"background": {
  "scripts": [
    "background.js",
    "gapi-client.js"
  ]
}

在我的扩展中,background.js 是主要的后台脚本。所有 gapi-client.js 的内容都是从 https://apis.google.com/js/client.js 直接复制粘贴而来。

background.js 中包含了以下代码:

window.gapi_onload = function(){
  console.log('gapi loaded.', gapi.auth, gapi.client);

  // Do things you want with gapi.auth and gapi.client.
}
请注意,background.jsgapi-client.js之前加载。因为gapi-client.js一旦加载就会读取window["gapi_onload"]window.gapi_onload必须在它之前指定。

因此,window.gapi_onload会按预期调用,并且同时填充了gapi.authgapi.client

在我的解决方案中,我没有自己创建background.html,也没有修改内容安全策略。但是,请注意该解决方案文档相对较少,因此未来可能会发生改变。


1
很棒的解决方案!我也发现了同样的问题,但即使使用windo.gapi_onload在模块化应用程序中也不是很方便(我正在编写backbone.js应用程序)。你没有找到任何有用的API包装器吗? - Artem Volkhin
4
当我在我的清单中包含gapi-client.js文件时,它会尝试在background.html源中包含来自apis.google.com的第三方外部脚本。你看到这个问题了吗?因为对我来说实际上是相同的错误。这是该脚本的完整URL:https://apis.google.com/_/scs/apps-static/_/js/k=oz.gapi.en.7_g8FbFMIhg.O/m=client/rt=j/sv=1/d=1/ed=1/am=AQ/rs=AItRSTNRC9ZdcUhJFGX80OZ8GW_8Ym1GpA/cb=gapi.loaded_0。 - not_shitashi
刚刚试了一下,对我没用。它打印出 undefined undefined。我认为可能是自从这个答案发布以来客户端脚本已经改变了。第一个答案(修改CSP)确实有效。 - Yossi Vainshtein
那个完美地运行了。初始化gapi之后,我只需要获取chrome token并将其发送以获取用户信息。救了我的一天。谢谢!如果你只是复制粘贴,是的,它会返回undefined undefined,因为你必须有一个token才能使用它。 - Oliver White

3
您可以通过加载background.js的background.html来加载它们。
<html>
 <head>
  <title></title>
  <script src="background.js"></script>
 </head>
 <body>
 </body>
 <script src="https://apis.google.com/js/client.js"></script>
</html>

使用manifest.json:

"background":
{
 "page": "background.html"     
}, 
"content_security_policy": "script-src 'self' https://apis.google.com; object-src 'self'",

1
我尝试按照 woojoo666 的建议添加清单文件,但仍然失败了, 看起来我们需要再添加一个标记 'unsafe-eval':

"content_security_policy": "script-src 'self' 'unsafe-eval' https://apis.google.com; object-src 'self'",


我遇到了错误:'content_security_policy.extension_pages',指令中的不安全内容安全策略值为"'unsafe-eval'" - AlwaysLearning

1

问题在于加载库,而非我为了简化而省略的回调函数。 - woojoo666
实际上,这解决了我遇到的一个次要问题,但并没有解决主要问题...无论如何还是谢谢!我编辑了我的帖子以防止混淆。 - woojoo666

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接