Denver.Y

 

ajax 缓存 问题 requestheader

在web开发的时候经常需要用到ajax,但是有些问题往往会被忽略,如果提交后需要在服务端做一些后台操作的话因为浏览器默认状态下有缓存的原因,可能页面上的信息还是正确的,但是后台的逻辑代码却没有真正的更新。这样是为了减少频繁访问服务器对其造成不必要的负担,但是同时也带来了一定特殊业务逻辑满足不了的问题。

例如: 

  需要通过前台一个select下拉列表来作为ajax的触发入口,同时将server返回的信息呈现在页面,并且往session或者数据库里面更新一些实际的东西的逻辑操作。

当第一次切换选项,也就是提交请求的时候一切都是正常的,但是如果切换相同选项因为浏览器的缓存原因,将不会走到server,实际得到的动态信息是从缓存中去取的。造成后台的逻辑没有被走到。代码如下:

aspx相关代码

                                
<asp:DropDownList ID="ddlProductList" runat="server">                                
                                    
<asp:ListItem Value="" Selected="True"></asp:ListItem>
                                    
<asp:ListItem Value="null">積立利率変動型終身保険</asp:ListItem>
                                    
<asp:ListItem Value="QIWL">  ・QIWL(H9)</asp:ListItem>
                                    
<asp:ListItem Value="KIWL">  ・KIWL(H11)</asp:ListItem>
                                    
<asp:ListItem Value="JIWL">  ・JIWL(H15)</asp:ListItem>
                                    
<asp:ListItem Value="null">積立利率変動型終身保険(市場金利連動型)</asp:ListItem>
                                    
<asp:ListItem Value="IIWL">  ・IIWL</asp:ListItem>
                                    
<asp:ListItem Value="HIWL">  ・HIWL</asp:ListItem>
                                    
<asp:ListItem Value="null">積立利率変動型終身保険(貯蓄重視型)</asp:ListItem>
                                    
<asp:ListItem Value="KIWLS">  ・KIWLS</asp:ListItem>
                                    
<asp:ListItem Value="null">ドル建積立利率変動型終身保険</asp:ListItem>
                                    
<asp:ListItem Value="ODIWL">  ・ODIWL</asp:ListItem>
                                    
<asp:ListItem Value="JDIWL">  ・JDIWL</asp:ListItem>
                                    
<asp:ListItem Value="HDIWL">  ・HDIWL</asp:ListItem>
                                    
<asp:ListItem Value="null"> 積立利率変動型養老保険(貯蓄重視型 米ドル建) </asp:ListItem>
                                    
<asp:ListItem Value="JDISE">  ・JDISE</asp:ListItem>
                                
</asp:DropDownList>

 

aspx.cs代码

            
if (!IsPostBack)
            {
   
                
//为doropdownlist添加客户端事件

                ddlProductList.Attributes.Add(
"onchange""selectChange(this)");

                
            }

 

Ajax.js代码
var request;

function selectChange(obj) {
        createHttpRequest();
        
var url = "AjaxService.aspx?product=" + obj.value;        
        request.open(
"GET",url,true)
        request.onreadystatechange 
= resetRate;        
        request.send();
        
return false;
    }
function createHttpRequest () {
    
if (window.ActiveXObject) {
        request 
= new ActiveXObject("Microsoft.XMLHTTP"); 
    } 
else if (window.XMLHttpRequest) {
        request 
= new XMLHttpRequest();
    }
}             
function resetRate() {     
    
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 = "";
       } 
    }    
}

 

请求页面代码
protected void Page_Load(object sender, EventArgs e)
        {
            
string productShortName = Request.QueryString["product"];            
           
            
if (productShortName != null && productShortName != "null" )
            {
                
string result = 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");

从服务端设置Header,其默认值为"private"修改为"no-cache"将实现,每次发送请求都会去服务端走一次。 

 

 

 

posted on 2010-02-09 11:40  Denver  阅读(4912)  评论(2编辑  收藏  举报

导航