REST / Ajax querie are part of our day as a web developer.
Recently, we had to handle response headers (when communicating with Basecamp3 API).
The default jqXHR object is not very helpful to give us a beautiful list of all response headers.
There are 2 functions available:
- getResponseHeader(key…) that returns the value of that key, but you need to know which one you need.
- getAllResponseHeaders, that returns a “string” of all headers, in key-value pair, but all stuck in 1 big string.
Solution
So, we create something that is, on every call, parsing that string and set it in a easy-to-use object embedded to the jqXHR.
$.ajaxPrefilter(function (options, originalOptions, jqXHR) { jqXHR.done(function (results, responseText, jqXHR) { getResponseHeaders(jqXHR); }) } function getResponseHeaders(jqXHR){ jqXHR.responseHeaders = {}; var headers = jqXHR.getAllResponseHeaders(); headers = headers.split("\n"); headers.forEach(function (header) { header = header.split(": "); var key = header.shift(); if (key.length == 0) return // chrome60+ force lowercase, other browsers can be different key = key.toLowerCase(); jqXHR.responseHeaders[key] = header.join(": "); }); }
Now, you can get, jqXHR.responseHeaders.etag value directly. (lowercase)
Because the “.done” set in ajaxPreFilter is set before the one of the caller, we can fill the responseHeaders property on all call. And, when the caller gets its .done event executed, that third parameter, jqXHR, contains the responseHeaders already filled.
Warning
You will be able to retrieve these headers, if you do same-domain query. For cross-domain queries, the server needs to return that header: Access-Control-Expose-Headers (more details)