如何在使用ajax时清除缓存数据?

时间:2010-07-22 11:57:49

标签: ajax

我正在使用Ajax根据一些ID从服务器检索数据,以执行自动建议功能。但是,当我提交表单并更新数据库时,自动建议字段假设不应再包含此ID的任何内容,但它仍将从其缓存中检索数据。有谁知道如何清除缓存并使Ajax发送请求每次按下按钮从服务器获取最新数据?请帮助我整整几个星期都坚持下去,无法找到解决方案。

例如:当ID字段为00001时,自动建议字段为1,2,3。在我提交表单并更新数据库之后,当我再次搜索00001时,它不应包含任何内容,但它仍然会将数据缓存为建议字段中的1,2,3 ......

if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
 xmlhttp=new XMLHttpRequest();
}
else
 {// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
  {
var data=xmlhttp.responseText;
alert(data);

}
}
xmlhttp.open("GET","gethint.php?q="+str,true);
xmlhttp.send();

6 个答案:

答案 0 :(得分:5)

之前我遇到过这个问题。这可能是您可以在服务器设置中修复的内容。服务器所做的是获取服务器请求,构建答案,当再次完成相同的请求时,它会发送它之前构建的相同响应。

为了轻松避免这个问题,我添加了一个额外的请求参数(一个UID)。 这样:

xmlhttp.open("GET","gethint.php?q="+str+**"?something"=RANDOMGUID**,true);

这样你总是有一个独特的要求。

答案 1 :(得分:2)

适用于IE8

xmlHttp.open("GET", URL, true);
xmlHttp.setRequestHeader("Cache-Control", "no-cache");
xmlHttp.setRequestHeader("Pragma", "no-cache");
xmlHttp.setRequestHeader("If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT");

答案 2 :(得分:0)

您可以使用http标头来阻止缓存响应:

Cache-Control: no-cache
Expires: Mon, 24 Oct 2005 16:13:22 GMT

另一种选择是在url中添加另一个参数,每次都会变化(例如以毫秒为单位的当前时间),对于浏览器,您会询问另一个URL,并且不会使用缓存。

答案 3 :(得分:0)

最简单的方法是使用jQuery#ajax并禁用缓存。

jQuery会为你的ajax调用添加参数?somenumber,这足以说服浏览器不能使用缓存数据。

我曾经遇到过这个。这是我得到的答案:Why does jQuery.ajax() add a parameter to the url?


您也可以手动执行相同的操作,但是您必须检查是否添加了参数。

答案 4 :(得分:0)

没有提供代码,但有一些指导可以帮助您在许多潜在的标签页,历史记录,设备等中统一管理帐户状态:

首先,一个长段中更精简的版本:

如果您想要一个帐户的一致视图,无论历史后退/前进按钮,额外标签或额外窗口(即使使用不同的IP /设备),您都可以使用增量计数器和心跳(心跳可以实现为在setInterval调用期间配置为2秒的XMLHttpRequest send())。增量在服务器上管理。客户端在每次调用服务器时都提供计数器值。在每个请求中,服务器使用自己保存的值检查客户端提供的计数器值。服务器生成下一个计数器值,保留它,并在回复中返回该计数器值,以便客户端可以在下次调用时使用它。如果客户提供了预期的计数器值,那么它就是一个好的"请求。如果提供的值与服务器存储的值不同,则客户端的呼叫是“坏”"请求。尊重好请求。服务器可能只部分地承认不良请求。客户"下一个"呼叫可能是该帐户的下一个心跳或任何其他请求。该帐户的多个客户端视图可以重叠,但基本上只有一个客户端才能获得下一个良好的调用。所有其他客户端将在下次调用时收到错误,因为它们的计数器值将不再与服务器存储的值相匹配。如果您使用一个帐户视图,则一旦启动会话,每次调用服务器都应该是一个很好的调用。 [会话可以持续浏览器javascript维护计数器值,但除非您使用cookie等,否则如果页面被刷新,则无法扩展会话,因为javascript将被重新初始化。这意味着每次第一次调用页面都会出现错误的情况。如果你使用历史记录,其他一些标签或其他设备,你应该可以使用它,但是当你从一个切换到另一个时,你将至少得到一个糟糕的呼叫。要限制这些错误的呼叫案例,请在浏览器视图处于非活动状态时关闭心跳。请注意,如果您不介意长时间向用户显示可能过时的页面,或者特定页面不太可能过时(或者此问题假设您可以获得陈旧数据),请不要实施心跳在用户的浏览器视图中。)

让我们添加更多细节:

从现有已打开的浏览器页面向服务器发出的每个请求都会提供计数器值。例如,这可以在表单提交期间或在javascript XMLHttpRequest对象.send()期间。

用户从网址栏输入的请求可能没有发送计数器值。此登录和登录只能被视为具有不正确的计数值。这些将是"坏"调用,应尽可能优雅地处理,但如果您想要一致的视图,通常不允许更新帐户。

每个寻求修改帐户的请求("编写者")都必须提供预期的计数器值(如果您有更复杂的需求,可以在服务器上更新,而不是+1)但必须是预期/唯一的下一个请求)。在服务器端,如果计数器值是预期值,则正常处理请求变量并允许写访问。然后在客户端的回复中包含服务器对该变量所期望的下一个合法值(例如,cnt ++)并在服务器端保留该值(例如,在数据库或某些其他服务器文件中更新计数器值)以便服务器每当下一个请求进入该帐户时,我们都会知道下一个合法的计数器值。

一个简单的"读取"处理方式与写入请求相同,但如果它是一个错误的请求(如果计数器不匹配),则更有可能安全地处理读取。

提供与预期不同的计数器值的所有请求("错误的"请求)仍会导致服务器上的计数器更新,并且仍会导致客户端的回复获得良好的下一步预期的反值;但是,在他们要求更新帐户的范围内,应忽略这些错误请求。糟糕的请求甚至可能导致更激烈的操作(例如将用户注销)。

客户端javascript将在每个服务器回复服务器返回的内容时更新计数器的值,以便在任何下一次调用时(例如,在心跳或与服务器的任何通话中)发回该更新的计数器值。每个客户端请求将始终获得一个合法的下一个值,但是只有使用该值的客户端才会被服务器视为正常。

其他客户端(即,没有提供预期计数器值的任何客户端请求)将被赋予安全状态,例如,根据数据库的当前状态,同时忽略任何写入/更新请求。服务器可以处理"坏"客户以其他更激烈的方式呼叫,例如,通过记录用户或其他任何方式,但主要是确保最多尊重不良客户端的安全读取请求,而不是以任何方式更新帐户。

只有在短时间内想要干净的视图时才需要心跳。要使服务器上的指示灯亮起,您可以将心跳设置为简单的ping(发送计数器值)。如果被认为是好客户,那么您可以为心跳做好准备。如果你是一个糟糕的客户端,那么服务器可以返回说好的新信息,可以由心跳代码中的javascript使用来更新GUI。心跳可以是不同的php服务器页面或主服务器页面,但如果不同,请确保页面获得服务器保存的计数器变量的一致视图(例如,使用数据库)。

您可能希望为帐户实施的另一项功能是"活动/非活动状态。如果鼠标位置没有改变数秒或分钟(并且在此期间没有键入键或其他用户输入),则客户端将处于非活动状态。当客户端处于非活动状态时,心跳可以自行停用(clearInterval)。在每个用户输入上检查心跳是否停止,如果是,则重新启动它。心跳重启也意味着用户正在从非活动状态更改为活动状态。当用户在其他选项卡或afk上浏览时,停止心跳将节省客户端/服务器资源。再次变为活动状态时,如果用户长时间处于非活动状态,则可以执行注销等操作...或者除了重新启动心跳之外不做任何新操作。 [请记住,对心跳的回复可能表明心跳请求是"坏" ..这可能是一个"激烈的"如上所述将用户注销的原因。]

答案 5 :(得分:0)

我知道答案已被接受,但在我的案例中并没有起作用。我已经添加了no-cache标头。在我的情况下,这是真正有效的解决方案,因为如果您在请求之后添加代码,则可能无法及时执行第二段代码成功运行:

x = new XMLHttpRequest();
x.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
        //execute the other code or function only when the page is really loaded!
    }
};
x.open("GET", "add your url here", true);
x.send();