Internet Explorer 7中Ajax链接仅加载一次

13

我正在编写一个应用程序,想要添加简单的AJAX功能。在Mozilla Firefox中效果很好,在Internet Explorer中有一个有趣的bug:每个链接只能被点击一次。必须完全重新启动浏览器,简单地重新加载页面是行不通的。我编写了一个非常简单的示例应用程序来演示这一点。

以下是Javascript代码:

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;
}

非常感谢任何帮助。

8个回答

16

这是因为Internet Explorer会忽略no-cache指令,并缓存ajax调用的结果。随后,如果下一个请求完全相同,它将只提供已缓存版本。有一个简单的解决方法,就是在查询末尾附加随机字符串。

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

根据我的经验,添加我上面发布的三个头部信息将防止IE缓存,无需附加随机数。 - pkaeding

6

看起来IE正在缓存响应。如果你将调用更改为POST方法,或发送适当的标头告诉IE不要缓存响应,那么它应该可以正常工作。

我发送的标头以确保它不被缓存是:

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

请注意,过期日期可以是过去的任何时间。

如何准确地设置这些头信息?我应该使用 PHP 的 header() 函数吗?还是在 HTML 中设置?我有点困惑。 - stillinbeta
是的,PHP的header()函数可以用来添加这些。 - Mark Renouf
在ColdFusion中,您可以使用cfheader标记使用名称和值属性传递它们。由于某种原因,我不得不将no-store添加到Cache-Control中,当然,在IE 8中甚至这也不起作用,但至少在IE 7和Firefox 3中可以。 - Dave DuPlantis

3
问题在于当响应处理程序在调用“open”之前设置时,IE会做一些奇怪的事情。对于第一个xhr请求,您没有这样做,但是由于重复使用xhr对象,当第二个“open”被调用时,响应处理程序已经设置好了。这可能令人困惑,但解决方案很简单。为每个请求创建一个新的xhr对象:
移动:
var xmlHttp = new XMLHttpRequest();

在 select 函数内部。


谢谢,这个方法很有效。但需要注意的是,我必须将事件处理程序移动到函数内部,以便它具有读取xmlHttpRequest变量的作用域。 - stillinbeta
经过仔细检查,这似乎没有解决问题。 - stillinbeta

1
在IE AJAX情况下对我效果最好的响应头是Expires: -1,这可能不符合规范但在微软支持文章(如何在Internet Explorer中禁止缓存)中提到。 这与Cache-Control:no-cachePragma:no-cache一起使用。

1

1
使用Dojo,可以使用dojo.date.stamp来完成此操作,只需将以下内容添加到URL中即可:
"...&ts=" + dojo.date.stamp.toISOString(new Date())

0

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

我同意这个观点...它完美地解决了这个问题。 问题在于IE7的url缓存非常糟糕,忽略了no-cache头并使用其url作为索引键将资源保存到其缓存中,因此最好的解决方案是向GET url添加一个随机参数。


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接