jQuery: No headers on success

I've been working in my spare time on a pure js UI using jQuery. While I love jQuery, the inconsistency of its AJAX callback handlers has been driving me nuts. What I needed was to handle pagination on a collection of resources by putting the pagination meta-data (stuff like which page was being rendered and how many resources per page) in the response headers. And of course, there is no way to get hold of the headers on success() because the success callback gives you only data and status. On the other hand the error handler gives me xmlHttpRequest, textStatus and errorThrown and xmlHttpRequest.getResponseHeader() would give me the response headers. But only if there was an error. Which there wasn't.

After a bunch of googling, the only solution I found looked something like this:
...
var xhr = $.post(form.action, params, function(data) {
if (xhr.getResponseHeader('Stripes-Success')) {
$('#form').hide();
$('#people').html(data);
}
else {
$('#form').html(data);
}
});
...

This forces me to create the handler when invoking an ajax method like $.post or $.get so that I could form a closure around the xhr (XmlHttpRequest) instance returned by them and make it available to my handler. A gross misuse of closures. Also, if I construct my handlers elsewhere (which is the case), I'm all outta luck.

I figure that rather than jumping through hoops or using closures for all the wrong reasons, I'd much rather patch jQuery. The fix turned out to be surprisingly simple and applies to lines 2815 to 2818 in jQuery 1.2.6. I changed
function success(){
// If a local callback was specified, fire it and pass it the data
if ( s.success )
s.success( data, status);
to
function success(){
// If a local callback was specified, fire it and pass it the data
if ( s.success )
s.success( data, status, xhr );

The best part is that no existing code is broken by this change. Now to get hold of the headers in a success handler, here's what you need to do:
function(data, textStatus, xhr) {
Console.debug(xhr.getResponseHeader("Page"));
Console.debug(xhr.getResponseHeader("Per-Page"));
}
Post a Comment