在应用中,如果我们使用GET方式(POST提交方式无此问题)提交交易数据,插入记录内容操作时等,对于此类的实时性的数据必须避免缓存,但有时会遇到时浏览器缓存的干扰,导致取不到最新的数据。解决的办法有两种:
1、在XMLHttpRequest发送请求之前(即open之后send之前)加上XMLHttpRequest.setRequestHeader("If-Modified-Since","0"),然后再使用send方法,下面以Delphi中使用XMLHTTPRequest为例进行说明,其它语言和脚本也是一样的,如下:
关键就是: HttpReq.setRequestHeader('If-Modified-Since', '0');
procedure TTestForm.ExecAddFeeByXMLHttp(const useGet: Boolean); var url,UsrPwd_Base64: string; HttpReq:IXMLHTTPRequest; JsonParamStr:string; begin Memo1.Lines.Clear; Memo1.Lines.Add('XMLHTTPRequest '+RadioGroup1.Items[RadioGroup1.ItemIndex]+'方式付款:'); Memo1.Lines.Add('===================================='); HttpReq := CoXMLHTTP.Create;//早期版本如Delhp7中则为 HttpReq := CoXMLHTTPRequest.Create; //两种提交请求的方式:Get和Post,Get是通过URL地址传递参数如果是中文需要转码,需要添加时间戳 Post不需要添加时间戳 //get url := 'http://localhost:5269/api/webmemberapi/NewMemberRegister?timestamp='+inttostr(Windows.GetTickCount); url := edt_SrvIp.Text+':'+edt_Port.Text+'/peci/rest/TServerMethods/AddFeeRecord/'; url := url+GetAddFeeParamStr_Delphi;//+'/'+datetimetostr(Time); if useGet then begin //http get httpReq.open('Get',url,False,EmptyParam,EmptyParam); end else begin //http post 如用post方法实际上是调用updateGetRoomInfo_ByRoom,post方式会在函数名前加上update前缀 HttpReq.open('Post', url, False, EmptyParam, EmptyParam); end; //HttpReq.setRequestHeader('Accept', 'application/x-www-form-urlencoded'); //HttpReq.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); if chk_Pwd.Checked then //如果服务器需要验证用户,请把验证信息放入Header中。 begin begin UsrPwd_Base64 := edt_User.Text+':'+edt_Pwd.Text; UsrPwd_Base64 := 'Basic '+EncodeString(UsrPwd_Base64);//'Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==' HttpReq.setRequestHeader('Authorization', UsrPwd_Base64); end; end; HttpReq.setRequestHeader('If-Modified-Since', '0'); HttpReq.setRequestHeader('Accept', 'application/json'); HttpReq.setRequestHeader('Content-Type', 'application/json'); HttpReq.setRequestHeader('Charset', 'utf-8'); //请求主体 try if useGet then begin //http get 如果url中已包含了参数,则无需在此再次传递参数 HttpReq.send(EmptyStr); end else begin //http post JsonParamStr := GetParamStr_Json;//GetParamStr_Delphi;// HttpReq.send(JsonParamStr); end; Memo1.Lines.Add(IntToStr(HttpReq.status)+'|'+HttpReq.statusText); Memo1.Lines.Add(HttpReq.responseText); except on Ex:Exception do Memo1.Lines.Add(Ex.Message); end; HttpReq := nil; end;运行结果:
2、在请求地址的末尾加入一个随机数作为参数,这样就能和上一次的请求区分开来。
js: URL = "http://host/a.php"+"?"+Math.random(); vbs: URL = "http://host/a.php"&"?"&Timer()
附:If-Modified-Since介绍
在http中Last-Modified 与If-Modified-Since 都是用于记录页面最后修改时间的 HTTP头信息,注意,在这 Last-Modified 是由服务器往客户端发送的 HTTP 头,另一个If-Modified-Since是由客户端往服务器发送的头,可以看到,再次请求本地存在的 cache 页面时,客户端会通过If-Modified-Since 头将先前服务器端发过来的 Last-Modified最后修改时间戳发送回去,这是为了让服务器端进行验证,通过这个时间戳判断客户端的页面是否是最新的,如果不是最新的,则返回新的内容,如果是最新的,则返回304 告诉客户端其本地 cache的页面是最新的,于是客户端就可以直接从本地加载页面了,这样在网络上传输的数据就会大大减少,同时也减轻了服务器的负担。
而且在一些ajax应用中,要求获取的数据永远是最新的,而不是读取位于缓存中的数据,做这样的设置是非常有必要的。