2010-07-22 60 views
1

我正在使用Ajax从服务器检索数据,如下所示,基于某些ID来执行自动提示功能。然而,当我提交表单并更新数据库时,auto建议字段假设不应该包含此ID的任何内容,但它仍将从其缓存中检索数据。有谁知道如何清除缓存,并使Ajax发送请求从服务器获取最新的数据,每次我按下按钮?请帮助我真的坚持了整整几周,并找不到解决方案。如何在使用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(); 
+0

你有这个问题,所有浏览器? – Anders 2010-07-22 12:06:14

回答

4

我曾经遇到过这个问题。这可能是您可以在服务器设置中修复的问题。服务器执行的操作是获取服务器请求,创建答案,并在相同请求再次完成时发送与之前构建的响应相同的响应。

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

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

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

+0

@Naelv是'RANDOMGUID'这样一个变量:'var x = Math.random()'?我现在有这个问题。它发生在我按下浏览器上的后退按钮时,无论出于何种原因,旧的'responseText'不会消失 – 2016-12-16 07:44:27

0

你可以使用HTTP标头以防止缓存响应:

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

另一种选择是另一个参数添加到不同每次(例如以毫秒当前时间)的URL,这样对你要求浏览器另一个网址和缓存将不会被使用。

0

最简单的事情就是使用jQuery#ajax并禁用缓存。

jQuery将为您的ajax调用后缀一个参数?somenumber,这足以说服浏览器不能使用缓存数据。

我碰到过这一次。这是我得到的答案:Why does jQuery.ajax() add a parameter to the url?


您也可以手动执行同样的操作,但是您必须检查参数的添加是否全部存在。

1

工程与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"); 
+0

不适用于发布 – 2016-12-16 08:02:00

0

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

首先,更多的浓缩版一个长段:

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

让我们添加更多的细节:

从现有打开的浏览器分页到服务器的每个请求提供计数器值。这可以是,例如,在表单提交期间或在JavaScript XMLHttpRequest对象.send()期间。

请求由用户从网址栏中键入可能不具有发送计数器值。这和登录只能被视为具有不正确的计数值。这些将是“不良”电话的例子,应尽可能优雅地处理,但如果您想要一致的视图,通常不应允许更新帐户。

每个要求修改帐户的请求(“编写者”)都必须提供预期的计数器值(如果您有更详尽的需求,但必须预期/唯一下一个请求)。在服务器端,如果计数器值是预期值,则正常处理请求变量并允许写入访问。然后在客户端的回复中包含服务器对该变量期望的下一个合法值(例如,cnt ++),并在服务器端保存该值(例如,更新数据库或其他服务器文件中的计数器值),以便服务器将知道下一个合法计数器值,以期在下一个请求进入该账户时预期。

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

提供高于预期(“坏”的请求)不同的计数器值的所有请求仍然导致计数器在服务器上更新,仍然导致客户端的答复得到很好的下一个预期的计数器值;但是,如果他们要求更新帐户,那么这些不良请求应该被忽略。错误的请求甚至可能导致更为激烈的操作(例如,将用户注销)。

客户端的JavaScript将在每个服务器回复一下服务器退回,使得该更新的计数值发回任何未来呼叫(例如,在心跳或任何谈话服务器)更新计数器的值。每个客户端请求总是会得到一个合法的下一个值,但只有首先使用它的客户端才会被服务器视为确定。

其他客户端(即不能提供预期的计数器值的任何客户端请求)将改为给予安全状态,例如,当前状态为每而忽略任何写入/更新请求的数据库。服务器可以以其他更为激烈的方式处理“不良”客户端调用,例如,通过将用户登出或以其他方式登录,但主要是确保最多承认不良客户端的安全读取请求,而不是以任何方式更新帐户。

只有在短时间内想要清晰视图时,才需要检测心跳。为了让它在服务器上亮起,可以让心跳成为简单的ping(发送计数器值)。如果被认为是优秀的客户,那么可以为心跳做好准备。然而,如果你是一个糟糕的客户端,那么服务器可以返回一个很好的新鲜的信息,它可以被心跳代码中的javascript用来更新GUI。心跳可以是不同的PHP服务器页面或主要页面,但如果不同,请确保页面获得服务器保存的计数器变量(例如,使用数据库)的一致视图。

您可能希望为某个帐户实现的另一个功能是“活动/非活动状态”。如果鼠标位置在几秒或几分钟内没有改变(并且在此期间没有键输入或其他用户输入,心跳可以在客户端处于非活动状态时自行关闭(clearInterval)每个用户输入都检查心跳是否停止,如果是,重新启动心跳重启也意味着用户正在从非活动状态变为活动状态停止心跳会节省客户端/服务器资源,当用户在其他选项卡或afk上浏览时,如果再次变为活动状态,您可以执行诸如注销用户,如果他们长时间处于非活动状态等等,或者除了重新启动心跳以外不做任何新操作。 ,对心跳的回复可能表明心跳请求是“不好的”..这可能是一个“激烈”的理由来登录用户作为我上面提到。]

+0

此“解决方案”解决user2230470所做的评论,这不是主要问题问,但相关的一点是随机化技巧至少在一些浏览器上不能解决问题,因为在某些时候,如果你不得不处理刷新(刷新会再次发送相同的数字而不是新的随机数)。这个解决方案更进一步(尤其是心跳),无论是看旧页面还是多个打开的窗口或设备,用户都几乎可以随时获得一个干净的更新视图。 – 2017-02-01 08:02:34

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();