Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Loading Google API Javascript Client Library into Chrome Extension

I've been trying to wed the google api javascript client library with a chrome extension for a while now, but it seems the chrome extension has a terrible case of cold feet. The link to the script is

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

Downloading the files is messy because the script actually loads other scripts. I've tried including it in the manifest

manifest.json (excerpt)

"background": {   "scripts": [     "background.js",     "https://apis.google.com/js/client.js?onload=callbackFunction"   ] }, 

but then the extension doesn't load. I've also tried injecting the script into the background html

background.js (excerpt)

 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); 

but the chrome debugger gives me

Refused to load the script 'https://apis.google.com/js/client.js' because it violates the following Content Security Policy directive: "script-src 'self' chrome-extension-resource:".

Any ideas, or are they fated to be kept apart?

Edit: note that you must add "?onload=myCallbackFunction" to the script url if you want to utilize a callback function. Thanks Ilya. More info here

like image 976
woojoo666 Avatar asked Sep 08 '13 08:09

woojoo666


2 Answers

So far the only solution I've found is to first inject the script into the background html page like I did:

background.js (excerpt)

 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); 

And then to bypass the security warning, edit the manifest file (source):

manifest.json (excerpt)

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

However, note that bypassing the security only works for https links, and I also find it kind of hacky...any other solutions are welcome

like image 59
woojoo666 Avatar answered Oct 09 '22 13:10

woojoo666


I found something interesting in the source code of https://apis.google.com/js/client.js. It reads:

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

gapi.load is invoked as soon as client.js is loaded in the webpage. It seems like window.gapi_onload will be invoked as a callback once gapi.client is loaded.

As a proof of concept, I built this plunker: http://plnkr.co/edit/TGvzI9SMKwGM6KnFSs7U

Both gapi.auth and gapi.client are successfully printed to console.


Back to Chrome extensions.

I put this in the background section of my mainfest.json:

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

in which background.js is the main background script in my extension. All content of gapi-client.js is directly copy-and-pasted from https://apis.google.com/js/client.js.

Inside background.js it reads:

window.gapi_onload = function(){   console.log('gapi loaded.', gapi.auth, gapi.client);    // Do things you want with gapi.auth and gapi.client. } 

Please note that background.js is loaded prior to gapi-client.js. Because gapi-client.js reads window["gapi_onload"] as soon as it's loaded, window.gapi_onload must be specified before that.

As a result window.gapi_onload is invoked as expected, with both gapi.auth and gapi.client populated.

In my solution I did not create a background.html on my own. I did not modify the content security policy either. However, notice that the solution is rather undocumented, thus is subject to change in the future.

like image 45
MrOrz Avatar answered Oct 09 '22 12:10

MrOrz