Verbose Logging

software development with some really amazing hair

T + G I F R

Hijack AJAX Requests Like A Terrorist

· · Posted in Programming
Tagged with

AJAX requests are a grand thing. They let you request things from your server without refreshing the page. Now, if you are trying to proxy a page, you can rewrite all the links in the page to point back through your proxy, but AJAX requests are another thing.

Oh wait no they're not!

You can't rewrite them when you proxy the page (by proxy, I mean you request my page with a URL param to another page, and I pull in that page, do some stuff, and serve it to you), but you still want the AJAX to go through your proxy, since otherwise it won't work.

Luckily there's a solution!

No matter what framework you use, jQuery, Prototype, whatever, they all go through the XMLHttpRequest interface. That is unless you are rockin' IE6, in which case they use an ActiveXObject. I don't deal with that, although I'm sure you can do something similar with it.

Anyway.

So you have this XMLHttpRequest thing, and as an example, in the jQuery code they do this:

new window.XMLHttpRequest();

See that new in there? They are creating a new object (for varying definitions of object). But whatever, this means we can use the magic of prototype. There's a bunch of stuff out there, so I won't cover it, but let's get some code.

And it works like this:

So check this out. First, we define an anonymous function that we call immediately:

(function() {
})();

The reason we need to do this is so that we can have a reference to the original open method without having to have other weird things kicking around just for that. So we call the method with the original open method as the only parameter:

(function(open) {
})(XMLHttpRequest.open);

Then with the prototype method, we redefine the code method on all XMLHttpRequest objects:

XMLHttpRequest.prototype.open = function(method, url, async, user, pass) { }

While keeping the original method around so we can intercept calls to it.

// Do some magic
open.call(...);

Put it all together and you get the AJAX interception code.

Simply replace the // Do some magic comment with your code to rewrite the URL, or do whatever with the request. Now when you proxy the request, just prepend a script tag to the head element (make it the first element inside the head tag) so it gets loaded before any other of the scripts on the page.