zl程序教程

您现在的位置是:首页 >  后端

当前栏目

ajax缓存问题requestheader

缓存AJAX 问题
2023-06-13 09:14:16 时间
这样是为了减少频繁访问服务器对其造成不必要的负担,但是同时也带来了一定特殊业务逻辑满足不了的问题。
例如:
  需要通过前台一个select下拉列表来作为ajax的触发入口,同时将server返回的信息呈现在页面,并且往session或者数据库里面更新一些实际的东西的逻辑操作。
当第一次切换选项,也就是提交请求的时候一切都是正常的,但是如果切换相同选项因为浏览器的缓存原因,将不会走到server,实际得到的动态信息是从缓存中去取的。造成后台的逻辑没有被走到。代码如下:
aspx相关代码
复制代码代码如下:

<asp:DropDownListID="ddlProductList"runat="server">
<asp:ListItemValue=""Selected="True"></asp:ListItem>
<asp:ListItemValue="null">?立利率??有徒K身保?</asp:ListItem>
<asp:ListItemValue="QIWL">  ・QIWL(H9)</asp:ListItem>
<asp:ListItemValue="KIWL">  ・KIWL(H11)</asp:ListItem>
<asp:ListItemValue="JIWL">  ・JIWL(H15)</asp:ListItem>
<asp:ListItemValue="null">?立利率??有徒K身保?(市?鼋鹄?B?有?</asp:ListItem>
<asp:ListItemValue="IIWL">  ・IIWL</asp:ListItem>
<asp:ListItemValue="HIWL">  ・HIWL</asp:ListItem>
<asp:ListItemValue="null">?立利率??有徒K身保?(?蓄重?型)</asp:ListItem>
<asp:ListItemValue="KIWLS">  ・KIWLS</asp:ListItem>
<asp:ListItemValue="null">ドル建?立利率??有徒K身保?</asp:ListItem>
<asp:ListItemValue="ODIWL">  ・ODIWL</asp:ListItem>
<asp:ListItemValue="JDIWL">  ・JDIWL</asp:ListItem>
<asp:ListItemValue="HDIWL">  ・HDIWL</asp:ListItem>
<asp:ListItemValue="null">?立利率??有宛B老保?(?蓄重?型 米ドル建)</asp:ListItem>
<asp:ListItemValue="JDISE">  ・JDISE</asp:ListItem>
</asp:DropDownList>

aspx.cs代码
复制代码代码如下:

if(!IsPostBack)
{
//为doropdownlist添加客户端事件
ddlProductList.Attributes.Add("onchange","selectChange(this)");
}

Ajax.js代码
复制代码代码如下:
varrequest;
functionselectChange(obj){
createHttpRequest();
varurl="AjaxService.aspx?product="+obj.value;
request.open("GET",url,true)
request.onreadystatechange=resetRate;
request.send();
returnfalse;
}
functioncreateHttpRequest(){
if(window.ActiveXObject){
request=newActiveXObject("Microsoft.XMLHTTP");
}elseif(window.XMLHttpRequest){
request=newXMLHttpRequest();
}
}
functionresetRate(){
if(request.readyState==4){
if(request.responseText.substring(0,1)=="#"){
document.getElementById("systemErrorMsg").innerHTML=request.responseText.substring(1);
document.getElementById("rate").innerHTML="";
}else{
document.getElementById("rate").innerHTML=request.responseText;
document.getElementById("systemErrorMsg").innerHTML="";
}
}
}

请求页面代码
复制代码代码如下:
protectedvoidPage_Load(objectsender,EventArgse)
{
stringproductShortName=Request.QueryString["product"];
if(productShortName!=null&&productShortName!="null")
{
stringresult=Utility.GetProductRate(packageName);
Session["rate"]=result;
Response.Write(result);
}
}

经过分析问题出在XmlHttpRequest这个对象上面,切换选项后,并不是每次走到请求页面的逻辑中。查询了相关资料解决方案如下:
request.setRequestHeader("If-Modified-Since","0");
简单的说,Last-Modified与If-Modified-Since都是用于记录页面最后修改时间的HTTP头信息,只是Last-Modified是由服务器往客户端发送的HTTP头,而If-Modified-Since则是由客户端往服务器发送的头,可以看到,再次请求本地存在的cache页面时,客户端会通过If-Modified-Since头将先前服务器端发过来的Last-Modified最后修改时间戳发送回去,这是为了让服务器端进行验证,通过这个时间戳判断客户端的页面是否是最新的,如果不是最新的,则返回新的内容,如果是最新的,则返回304告诉客户端其本地cache的页面是最新的,于是客户端就可以直接从本地加载页面了,这样在网络上传输的数据就会大大减少,同时也减轻了服务器的负担。
另外还有另一个解决放案,不过还未经测试,理论上应该是可行的,就是在请求页面设置一下response的header:
Response.AddHeader("Cache-control","no-cache");