ajax 缓存 问题 requestheader
程序员文章站
2022-06-24 16:16:27
这样是为了减少频繁访问服务器对其造成不必要的负担,但是同时也带来了一定特殊业务逻辑满足不了的问题。 例如: 需要通过前台一个select下拉列表来作为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");
例如:
需要通过前台一个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");
上一篇: 去加油