使用 ajax 解决浏览器缓存功能
来源:互联网 发布:链接不到网络 编辑:程序博客网 时间:2024/05/21 10:04
使用ajax时候浏览器缓存功能造成的问题。
网站中使用到ajax的功能非常简单。这里先简单描述一下,有两个下拉框A,B。下拉框B的内容是根据用户对A的选择而变化的。这里的主要流程就一目了然了:
用户更改了下拉框A的选项;
浏览器向服务器发送一个异步的命令;
服务器接收到之后查询数据库;
服务器把查询结构封装成xml发送到客户端;
客户端解析xml数据,修改下拉框B的选项条目。
根据上面的大纲,先做第一步,在下拉框A上注册onchange事件。
<select id="area" onchange="AreaChange()">响应的JS函数是AreaChange(),很明显这个函数的任务就是发送一个异步命令到服务器端。
function AreaChange()
{
var area = document.getElementById("area").value;
var roleID = document.getElementsByName("rolename")[0].value;
var url = "PrivilegeUpdate?area=" + area + "&roleid=" + roleID;
createXMLHttpRequest();
xmlHttp.onreadystatechange = AreaChangeReady;
xmlHttp.open("GET", url, true);
xmlHttp.send(null);
}函数中首先得到下拉框选中的值,然后拼接成url,发送到服务器。由于是异步操作,因此还要注册一个接收消息的响应函数AreaChangeReady。
接下来就是服务器端的操作了,服务器端的代码我是用java写的。
public class PrivilegeUpdate extends HttpServlet
{
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
response.setContentType("text/html charset=UTF-8");
String area = request.getParameter("area");
areaDB Area = new areaDB();
lineTable [] lt = Area.getLine(area);
if(lt == null)
return;
StringBuffer results = new StringBuffer("<root><line>");
for(int i=0;i<lt.length;i++)
{
results.append("<id>");
results.append(lt[i].getLineID());
results.append("</id>");
results.append("<name>");
results.append(lt[i].getLineName());
results.append("</name>");
}
results.append("</line>");
results.append("</root>");
response.setContentType("text/xml");
response.getWriter().write(results.toString());
}
}这个类继承了HttpServlet类,并且重载了doGet方法,由于以xml的方式发送到客户端,设置ContentType为text/xml。然后根据返回的结果拼接xml字符串。
接下来就是客户端的AreaChangeReady开始执行了。
function AreaChangeReady()
{
if(xmlHttp.readyState == 4)
{
if(xmlHttp.status == 200)
{
updateLine();
updateUnAddPrivilege();
}
}
}第二个函数调用可以不去理会,重要的是updateLine函数,主要功能是更新下拉框B。
function updateLine()
{
clearLine();
var linexml = null;
linexml = xmlHttp.responseXML.getElementsByTagName("line");
var line = document.getElementById("line");
var option = null;
if(linexml == null || linexml.length == 0)
{
option = document.createElement("option");
option.setAttribute("value", "");
option.appendChild(document.createTextNode("无线路"));
line.appendChild(option);
return;
}
var lineID = linexml[0].getElementsByTagName("id");
var lineName = linexml[0].getElementsByTagName("name");
for(var i=0;i<lineID.length;i++)
{
option = document.createElement("option");
option.setAttribute("value", lineID[i].firstChild.nodeValue);
option.appendChild(document.createTextNode(lineName[i].firstChild.nodeValue));
line.appendChild(option);
}
}解析了服务器发来的xml数据,然后根据读取的数据更新下拉框B。
上面的代码从理论上来说没有问题,一些简单的测试也符合预期。但是在进一步的测试中就出现了莫名其妙的问题。我更新数据库中的数据,然后再进行选择下拉框A的操作,下拉框B并不会如我预期那样显示正确的数据。这里很显然,肯定就是浏览器缓存的原因了。
第一次选择下拉框A的时候浏览器会如预期一样向服务器发送请求,然后服务器返回,浏览器更新下拉框B的选项。但同时,浏览器也做了个小动作,保存了这个数据以备下一次使用。所以第二次,浏览器将不再向服务器发送数据,而是直接从缓存中拿出数据,更新下拉框B的选项。如果这时候更新了数据库,悲剧也就发生了。
明白了这个道理,解决方案当然也就出来了:不要让浏览器缓存这个xml数据。HTTP协议本身就可以设置浏览器是否进行缓存。
在servlet的doGet方法进行输出之前加入这么一行代码:
response.setHeader("Cache-Control", "no-cache");但是问题还是存在,虽然servlet中看上去只只有一个输出
response.getWriter().write(results.toString());但是方法还有一个出口那就是return。一开始我也以为return之后并不会向浏览器发送数据,但是我错了,虽然没有发送数据,浏览器也会把没有数据这个结果缓存起来。这个错误相当隐蔽,我被这个错误折磨了2天之后才突然明白过来。修改后的代码如下
public class PrivilegeUpdate extends HttpServlet
{
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
response.setContentType("text/html charset=UTF-8");
String area = request.getParameter("area");
String roleid = request.getParameter("roleid");
areaDB Area = new areaDB();
lineTable [] lt = Area.getLine(area);
if(lt == null)
{
response.setContentType("text/xml");
response.setHeader("Cache-Control", "no-cache");
response.getWriter().write("<root></root>");
return;
}
StringBuffer results = new StringBuffer("<root><line>");
for(int i=0;i<lt.length;i++)
{
results.append("<id>");
results.append(lt[i].getLineID());
results.append("</id>");
results.append("<name>");
results.append(lt[i].getLineName());
results.append("</name>");
}
results.append("</line>");
results.append("</root>");
response.setContentType("text/xml");
response.setHeader("Cache-Control", "no-cache");
response.getWriter().write(results.toString());
}
}经历过这次事件,以后使用ajax时候肯定会注意HTTP的Cache-Control属性。
解决方法:可以在url里加入时间或者随机数。
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/whatcanhumdo/archive/2010/09/14/5884793.aspx
- 使用 ajax 解决浏览器缓存功能
- 解决使用Ajax时浏览器的缓存问题
- 禁用Ajax使用浏览器缓存
- Ajax浏览器缓存问题的解决
- Ajax解决浏览器的缓存问题
- Ajax解决浏览器的缓存问题
- Ajax解决浏览器的缓存问题
- Ajax解决浏览器的缓存问题
- Ajax解决浏览器的缓存问题
- Ajax解决浏览器的缓存问题
- Ajax解决浏览器的缓存问题
- 浅谈Ajax解决浏览器的缓存问题
- ajax学习笔记---解决浏览器缓存和中文乱码问题
- 解决Ajax在IE浏览器中缓存问题
- ajax浏览器缓存问题
- AJAX浏览器缓存问题
- 使用ajax时浏览器何时缓存以及如何避免浏览器缓存
- 使PHP 使用AJAX时,让浏览器禁用缓存。
- Hessian轻量级二进制远程调用框架
- 三星S5PC110 S5PV210 智能手机TD/WCDMA/EVDO、平板电脑方案
- 玩转 Google开源C++单元测试框架Google Test系列(gtest)之八 - 打造自己的单元测试框架(转载)
- Android wifi porting
- 怎么能买房不花钱!
- 使用 ajax 解决浏览器缓存功能
- 我要做一个开心的我,一个追梦的我
- 连接两个文件的数据字段-join命令
- JDK 动态代理 & AOP实现动态代理
- ProwerDesigner基础知识
- 关于DM9000 的讨论
- Java发邮件
- Python学习(一) 数值
- left join,inner join,right join,cross join,full join的区别