Chrome Extension: Getting Those Ajax Queries

Published 2012-01-13 on Farid Zakaria's Blog


Warning: I am relatively new to Javascript. If the solution presented below seems trivial, please forgive.

Once again, I'm isolated

I remember the frustration of hacking things into a web page due to Chrome's Isolated World for their extensions. The problem I originally faced was that HypeMachine was storing the info for their tracks in variables that are restricted to the content scripts loaded by the extension.

Isolated worlds completely separate the JavaScript on the page from the JavaScript in extensions.

The second time around, my problem was not with accessing local data but getting access to jQuery instance used to make Ajax requests on the web page. The webpage for which I am writing the extension, refreshes its page via Ajax requests; after which it reconstructs the DOM programmatically. I could load jQuery myself into my extension however it would be a different instance! Any attempt to hook into the global Ajax event handlers would do no such good...

Isolated worlds allow each content script to make changes to its JavaScript environment without worrying about conflicting with the page or with other content scripts.

Breaking Free

It was pretty easy how I circumvented the issue the first time around,byinjecting the whole content script right into the web page! This let me write the script and have access to all the goodies of the page. This time however the solution is not doable for the new extension since I also wanted to make cross domain browser requests. My new solution would have to allow me to write the code in the extension's script but be notified of all Ajax requests...

Javascript on the main page are bound to make requests only to the original domain from where they came (Same Origin Policy), however scripts in the extension are allowed to make cross domain requests.


var main = function() {

   		var myEvent= document.createEvent('Event');
   		myEvent.initEvent('CustomEvent', true, true);

   		function fireCustomEvent() {
   			document.body.dispatchEvent(myEvent);
   		};

   		jQuery(document).ajaxComplete(function(event,request, settings){
			console.log("Ajax complete.");
			fireCustomEvent();
   		});

};

// Lets create the script objects
var injectedScript = document.createElement('script');
injectedScript.type = 'text/javascript';
injectedScript.text = '('+main+')("");';
(document.body || document.head).appendChild(injectedScript);

document.body.addEventListener('CustomEvent', function() {
	console.log("Received event!");
});

The solution above (somewhat described by Google here) demonstrates that the common denominator between the content scripts and the web page is the DOM. Though modification of the DOM you can pass data & propagate events. In the example above, I've injected my personal .ajaxComplete() handler which fires my custom event. The extension then listens for my custom event which is now technically a wrapper for the ajaxComplete event!

I know you can pass data through InnerText and by user jQuery's data method. However is it possible to serialize the actual jQuery instance from the web page and pass it to the extension?