views:

2734

answers:

6

I'm writing an application and I'm trying to tie simple AJAX functionality in. It works well in Mozilla Firefox, but there's an interesting bug in Internet Explorer: Each of the links can only be clicked once. The browser must be completely restarted, simply reloading the page won't work. I've written a very simple example application that demonstrates this.

Javascript reproduced below:

var xmlHttp = new XMLHttpRequest();

/*
item: the object clicked on
type: the type of action to perform (one of 'image','text' or 'blurb'
*/
function select(item,type)
{

 //Deselect the previously selected 'selected' object
 if(document.getElementById('selected')!=null)
 {
  document.getElementById('selected').id = '';
 }
 //reselect the new selcted object
 item.id = 'selected';

 //get the appropriate page
 if(type=='image')
  xmlHttp.open("GET","image.php");
 else if (type=='text')
  xmlHttp.open("GET","textbox.php");
 else if(type=='blurb')
  xmlHttp.open("GET","blurb.php");

 xmlHttp.send(null);
 xmlHttp.onreadystatechange = catchResponse;

 return false;

}
function catchResponse()
{
 if(xmlHttp.readyState == 4)
 {
  document.getElementById("page").innerHTML=xmlHttp.responseText;
 }

 return false;
}

Any help would be appreciated.

+5  A: 

It looks like IE is caching the response. If you either change your calls to POST methods, or send the appropriate headers to tell IE not to cache the response, it should work.

The headers I send to be sure it doesn't cache are:

Pragma: no-cache
Cache-Control: no-cache
Expires: Fri, 30 Oct 1998 14:19:41 GMT

Note the expiration date can be any time in the past.

pkaeding
How exactly to you set these headers? Would I use the header() function of PHP? Something in the HTML? I'm a little confused.
stillinbeta
Yes, the PHP header() function can be used to add these
Mark Renouf
And in ColdFusion you can use the cfheader tag to pass them using name and value attributes. For some reason I had to add no-store to Cache-Control as well, and of course in IE 8 even that didn't work, but at least it did in IE 7 and Firefox 3.
Dave DuPlantis
+6  A: 

This happens because Internet Explorer ignores the no-cache directive, and caches the results of ajax calls. Then, if the next request is identical, it will just serve up the cached version. There's an easy workaround, and that is to just append random string on the end of your query.

 xmlHttp.open("GET","blurb.php?"+Math.random();
tj111
In my experience, adding all three headers I posted above will prevent IE from caching, without needing to append a random number.
pkaeding
+2  A: 

The problem is that IE does wacky things when the response handler is set before open is called. You aren't doing that for the first xhr request, but since you reuse the xhr object, when the second open is called, the response handler is already set. That may be confusing, but the solution is simple. Create a new xhr object for each request:

move the:

var xmlHttp = new XMLHttpRequest();

inside the select function.

John C
Thanks, this did the trick. It should be noted, though, that I have to move the event handler within the function so it has the scope to read the xmlHttpRequest variable.
stillinbeta
Upon closer inspection, this doesn't seem to have solve the problem.
stillinbeta
A: 

xmlHttp.open("GET","blurb.php?"+Math.random();

I agree with this one.. it works perfectly as a solution to this problem. the problem is that IE7's caching of urls were terrible, ignoring the no-cache header and save the resource to its cache using its url as key index, so the best solution is to add a random parameter to the GET url.

+1  A: 

Read No Problems section in [link text][1] [1]: http://en.wikipedia.org/wiki/XMLHttpRequest

+1  A: 

The response header that has worked best for me in the IE AJAX case is Expires: -1, which is probably not per spec but mentioned in a Microsoft Support Article (How to prevent caching in Internet Explorer). This is used in conjunction with Cache-Control: no-cache and Pragma: no-cache.

Kevin Hakanson