ajax 清理缓存实例
ajax好处不用多说,如有:异步加载,实现局部刷新,提高用户体验,等等。
在用ajax做数据提交时,发现一个问题。每次提交之后,更新提示信息总是出现上一次的更新提示记录。
手动清理浏览器缓存之后,好像问题可以解决了。可是提交一次之后,第二次又是同样的问题。
下面看一下我做的一个小程序
做了一个小的网络投票程序,用ajax提交前台的投票数据给后台数据库。
问题要求简单描述如下:程序内部要求做好判断和提示,如果同一天内同一个IP只能限制投票一次;
如果第一次提交,则弹出“投票成功;第二次提交如果同一个主题已经存在的IP不能再次投票,则提示“不能重复投票”。
问题描述之后,似乎很简单了。
前台HTML提交的js脚本如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | function submitVote(obj) { var eve=getEvent(); var chr=document.getElementsByName( "netvote" ); var count=0; var selList= "" ; for ( var i=0;i<chr.length;i++){ if (chr[i]. checked ){ count++; selList+=chr[i].value+ "," ; } } if (count<1){ alert( "还没有选择" ); if (eve.preventDefault){eve.preventDefault();} else {eve.returnValue= false ;} return false ; } var postUrl= "/ashx/Vote.ashx?Id=" +obj+ "&optionId=" +selList Request.sendGET(postUrl, cackbackResult, null , null , null ); } function cackbackResult(req){ var str=req.responseText; if (str== "0" ) //如果没有选择选项 { alert( "没有选择" ); return false ; } if (str== "001" ) //已经投过的 { alert( "已经投过不能重复投票" ); return false ; } if (str== "002" ) { alert( "投票成功" ); location.href= 'default.html' ; } } 后台处理代码: public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/plain" ; int QId = Gain.GetQueryInt( "Id" , 0); //问题编号 string optionId = Gain.GetQueryString( "optionId" ); if ( string .IsNullOrEmpty(optionId)) { context.Response.Write( "0" ); //没有选项 } else if (QId > 0) { try { EEY.Lib.BLL.VoteIp bvIp = new EEY.Lib.BLL.VoteIp(); string Ip = Gain.GetUserIP; string strWhere = string .Format( "Ip='{0}' AND OptionId={1} AND DateDiff(d,voteTime,getDate())<1" , Ip, QId); if (bvIp.Exists(strWhere)) { context.Response.Write( "001" ); //同一个IP一天只能对某一个问题投一次票 } else { int optId = 0; string [] arry = null ; if (optionId.IndexOf( ',' ) >= 0) { optionId = optionId.TrimEnd( ',' ); if (optionId.IndexOf( ',' ) >= 0) //多项选择 { arry = optionId.Split( ',' ); } else { arry = new string [1] { optionId }; } } EEY.Lib.Model.VoteIp vmodel = new EEY.Lib.Model.VoteIp(); vmodel.Ip = Ip; vmodel.OptionId = QId; vmodel.VoteTime = DateTime.Now; bvIp.Add(vmodel); if (!arry.Equals( null )) { EEY.Lib.BLL.Option bopt = new EEY.Lib.BLL.Option(); for ( int i = 0; i < arry.Length; i++) { optId = StrUtil.ToInt32(arry[i], 0); bopt.UpdateCount(optId); } int total = bopt.GetQuestionVote(QId); EEY.Lib.BLL.Question bq = new EEY.Lib.BLL.Question(); if ( bq.UpdateVote(QId, total)>0) { context.Response.Write( "002" ); //添加成功 } } } } catch (System.Exception ex) { context.Response.Write(ex.Message); } } } |
通过测试发现,提交投票时候,同一个IP的确只能投一次,即查数据库票数记录即可以知道(第一次提交之后更新票数,但第一次提交之后票数都没有变过)。
每一次在前台点击投票都提示“投票成功”,实际上是没有更新记录。
显然不是我们要的结果。因此可以断定,肯定是ajax缓存问题,存在缓存的情况下它不会每次都执行后台代码。从而可以断定是前台提交的问题,及时的提交而不是返回缓存前一次的结果。
解决办法:
在提交时加上时间戮
即在postUrl处修改为:
var postUrl="/ashx/Vote.ashx?Id="+obj+"&optionId="+selList+"&guid="+new Date().getTime();
//+"&guid="+new Date().getTime();
加上这时间之后,问题解决。显然ajax实时的返回后台处理结果,我们目的达到。OK
总结
Ajax在解决缓存时有三种办法。
1、加时间戮
对于一个浏览器,你的第一次点击是会调用rpc请求的, 但是你再用同一个浏览器提交表单的时候, rpc不会被提交, 因为参数一样, 这个可能是ajax的XMLHttpRequest对象的问题, 如设置了时间间隔了,实际上是(new ActiveXObject("Microsoft.XMLHTTP"))所以, 在实际操作的时候, 给rpc的参数传递一个没有用的guid= new Date().getTime()
一个时间戳 ,以保证每次的点击事件都会激发rpc请求, 因为这样的参数(或者说url)是不一样的。
为什么要把时间戳追加到目标url?
在某些情况下, 有些浏览器会把多个XMLHttpRequest请求的结果缓存在同一个url。如果对每个请求的响应不同,这就会带来不好的结果。把当前时间戳追加到url的最后,就能确保url的唯一性,从而避免浏览器的缓存结果。
2、在要异步获取的页面中写一段禁止缓存的代码:
Response.Buffer =True
Response.ExpiresAbsolute =Now() - 1
Response.Expires=0
Response.CacheControl="no-cache"
3、在ajax发送请求前加上xmlHTTP.setRequestHeader("If-Modified-Since","0");可以禁止缓存
xmlHTTP.open("get", URL, true);
xmlHTTP.onreadystatechange = callHTML;
xmlHTTP.setRequestHeader("If-Modified-Since","0");
xmlHTTP.send();
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」