Farid Zakaria

Archive 3 min read

Chrome Extension: Getting Those Ajax Queries


This post comes from my original WordPress blog, written between 2009 and 2018. It is kept here verbatim as an archive — the formatting did not always survive the move, and I no longer agree with all of it.


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?

2 archived comments

Eray 2015-02-03

How can i pass data with event dispatch? i want pass xhr info’s :/

ncla 2015-10-11

I found out how you can pass the data through events. http://stackoverflow.com/questions/10526995/can-a-site-invoke-a-browser-extension

Though keep in mind if you pass some weird objects, for example from jQuery.ajaxPrefilter originalOptions, which has some proto stuff in it, it will fail. Which is really weird behavior. What I ended up doing instead if JSON.stringify and JSON.parse the object like so:

document.dispatchEvent(new CustomEvent(‘eventId’, {‘detail’: JSON.parse(JSON.stringify(data))}));