Caching, jQuery Ajax and Other IE Fun
Join the DZone community and get the full member experience.
Join For Freein the last couple of days i had quite a fun time debugging problems of our javascript spas on oldie (thanks god we got the browserstack licenses). anyway, i encountered some quite interesting behavior of ie with jquery ajax calls and cached responses.
“http/1.1 304 not modified”: no way! you won’t catch me
to have this experiment work, ensure you have your browser caches active.
take the following ajax request to a static json file
$.ajax({ url: '/data.json', type: 'get', datatype: 'json', success: function(data, textstatus, jqxhr){ console.log('data received: ' + data); } });
the first request probably returns with a
http/1.1 200 ok
while any subsequent (if caching is activated on the server) will return with a
http/1.1 304 not modified
. you nicely see this in chrome’s network panel
now, assume you’d like to perform some operation just on
http/1.1 200
and not on
304
requests as well. easy enough, right? you simply check against the
jqxhr.status
object:
... success: function(data, textstatus, jqxhr){ if(jqxhr.status === 200){ console.log('got a good request'); } }
interestingly though, for the above request i’d get
got a good request got a good request got a good request
…printed on my console and indeed, when checking against the jqxhr request, the
jqxhr.status
returns
200
for
http/1.1 200
as well as for
http/1.1 304
. why this?? this is
by design of the xmlhttprequest
object.
for 304 not modified responses that are a result of a user agent generated conditional request the user agent must act as if the server gave a 200 ok response with the appropriate content. […] w3c.org [rfc2616]
wait..there is a way!
actually there is a way to also get the
304
status codes in your jquery ajax callback. again:
… the user agent must allow setrequestheader() to override automatic cache validation by setting request headers (e.g., if-none-match, if-modified-since), in which case 304 not modified responses must be passed through. w3c.org [rfc2616]
but note, you don’t have access to the browser’s
if-modified-since
or e-tag information. jquery however keeps track about it and allows you to use the
ifmodified
flag on the ajax options:
$.ajax({ url: '/data.json', type: 'get', datatype: 'json', ifmodified:true, success: function(data, textstatus, jqxhr){ if(jqxhr.status === 200){ console.log('got a good request'); } else { console.log('hey, a 304 request'); } console.log('data: ' + data); } });
executing this now again, where the first request returns a 200 and the subsequent ones a 300 response status gives me the following on the log:
got a good request data: <snip>json string</snip> hey, a 304 request data: undefined hey, a 304 request data: undefined
hell, wtf?? yep, again this is by design:
[…] in which case 304 not modified responses must be passed through […]
..and indeed, a
304
response does not carry any data.
ok, but why should this be an issue?
normally it won’t, just don’t put the
ifmodified
flag and you’re fine. in my specific scenario however, i had to analyze for changes in a specific response header, so i used the
ajaxcomplete(..)
function like
var currentheaderval = undefined; $(document).ajaxcomplete(function(e, xhr, settings){ var newheaderval = xhr.getresponseheader('my-header'); if(currentheaderval !== newheaderval){ //do something fancy } });
on the server-side some mechanism injected the
my-header
value. the idea is simple and it also works (on chrome, firefox and any other decent browser) but, surprise, surprise, on ie it doesn’t. when using
xhr.getresponseheader('my-header')
, ie returns the
headers from the previously cached request
which obviously are not necessarily valid any more.
as such, the idea was to check the
xhr.status
in order to just read the headers from
200
type requests, like
var newheaderval = xhr.getresponseheader('my-header'); if(xhr && xhr.status === 200){ if(currentheaderval !== newheaderval){ //do something fancy } }
…but as we know now, that won’t work.
links
Published at DZone with permission of Juri Strumpflohner. See the original article here.
Opinions expressed by DZone contributors are their own.
Trending
-
Which Is Better for IoT: Azure RTOS or FreeRTOS?
-
Building a Robust Data Engineering Pipeline in the Streaming Media Industry: An Insider’s Perspective
-
13 Impressive Ways To Improve the Developer’s Experience by Using AI
-
MLOps: Definition, Importance, and Implementation
Comments