Using jQuery’s ajaxSend event to change an AJAX request

This post is more than 11 years old.

Customisation of web software sometimes requires that you get it to pass around some additional information whenever it makes a page request. Often, putting that information into a cookie isn’t appropriate, so you try to squeeze it into the page query parameters, or form post data through hidden fields. But what if the software makes AJAX requests from jQuery? Luckily, jQuery can help you intercept AJAX requests so that you can customise them too.

For a WordPress plugin I’ve been working on, I need to be able to inject an extra query parameter into an AJAX request. The data for the request is hard-coded into the JavaScript source, and I don’t want to monkey patch it because that can lead to constantly tracking the changes to that source file as WordPress evolves — and I do enough of that already, thangyouveramush.

Enter jQuery global AJAX event handlers. As it says on the manual page,

These methods register handlers to be called when certain events, such as initialization or completion, take place for any AJAX request on the page.

Perfect, I can intercept the AJAX request, and add my custom parameter. I just need to check that the AJAX request is going to the endpoint I’m targetting, so that I don’t go adding my parameter to every AJAX request :)

For my problem, I need to hack the call that WordPress’ media popup makes to retrieve information about a file that has just been uploaded via the admin UI. It’s an AJAX post request to an isolated PHP file, so it’s easy to add a query parameter onto the AJAX endpoint (I check for the parameter in a filter hook before modifying what the request returns). So I just need to inject this short jQuery script into the media popup’s HTML.

<script>
jQuery(function($) {
    $(document).ajaxSend(function(event, jqxhr, settings) {
        if (settings.url == "async-upload.php") {
            settings.url += "?wpwines=product";
        }
    });
});
</script>

Quick, simple, and job is done. Until the next time WordPress rewrites its media management module!