以文本方式查看主题

-  W3CHINA.ORG讨论区 - 语义网·描述逻辑·本体·RDF·OWL  (http://bbs.xml.org.cn/index.asp)
--  『 HTML/XHTML/Ajax/Web 2.0/Web 3.0 』  (http://bbs.xml.org.cn/list.asp?boardid=22)
----  Ajax里如何清除响应的cache数据  (http://bbs.xml.org.cn/dispbbs.asp?boardid=22&rootid=&id=45967)


--  作者:ohaiyo
--  发布时间:4/25/2007 12:15:00 PM

--  Ajax里如何清除响应的cache数据
如题: Ajax里如何清除响应的cache数据
--  作者:dogog
--  发布时间:5/6/2007 1:22:00 AM

--  
1、cache简述
    讨论比较多的是J2ee中的cahce,不管是集中式,分布式可能大家基本理解都差不多。但可能有个误区,不要把cache介质当成持久化介质,我觉得判断标准是,当cache服务器瘫痪时,不影响系统的应用,只是性能上受影响。
     在ajax中,我认为有两种应用场景。
    a、通过xmlhttp/iframe等向服务器请求内容时。因为每次http请求消耗的时间是很多的,对不常改变的数据进行cache可以大大的加快系统响应速度,可以节约服务器资源
     与j2ee比较,可能与hibernate二级缓存类似,数据cache.
    b、由于javascript语言性能不是很好,对于复杂的,费时的运算,我们也可以把运算结果cache.不知道大家知道不知道csdn中梅花雪做的那棵树,据说它用了cahce。
    我想这类cache叫应用cache。在j2ee应用中,我一般不做数据cache,只在logic层做cache.但现在通过ROR的学习,有点怀疑logic/dao层的必要性,毕竟我们做的真是“企业应用”吗?有复杂逻辑吗?

     在ajax cahce解决方案里,个人喜欢在做数据cache,也是上面的第一种。如果要在浏览器上做复杂的运算,那请你回头看看,你的设计肯定有问题,或者这个逻辑不应该由浏览器来完成。
2、ajax cache的特点
    这里ajax应用程序在浏览器中,cache在不同htm/jsp...页面中不能共享。(当然iframe,frame特殊处理,可能这是cache介质的好地方) ,更麻烦的是页面刷新以后,cache会丢失,好在我们的ajax应用可以设计成single page应用。

开始正题前,我想有两个假设
(1)在single page应用中。毕竟那是大家向往的一中ajax应用方式,也是cache最能发挥作用的场景。
(2)数据cache,通过xmlhttp,iframe,dwr等框架的cache.
    ajax的cache远没有j2ee等服务器端复杂,应用也有一定的局限,但以下问题应该考虑:
    
     a、限制条件
     b、哪些数据应该cache.
     c、cache key怎么设定。
     d、如何应用cache呢?
3、限制条件
    我想对于ajax应用来说,从服务器获取数据的入口应该是一个,例如:如果你准备用dwr,那么你程序中所有与服务器的交互必须都是DWR,如果用dojo.io。那么cache将比较难实现,必须手工编程来cache,remove cache 。不知道我的表述清楚没。就象在j2ee中,如果你用了hibernate的二级缓存,如果你用JDBC或着更新了数据库中内容,那hibernate的二级缓存内容肯定不是正确的了。所以如果要用ajax cache,与服务器交互的类库最好是一种。
     cache最大好处是提高系统性能,而ajax应用能够cache的数据并不是太多(后面描述),所以我们的cache框架必须精小,并且可拔插。
      dojo.io/dwr/json-rpc.....这类框架的选择也很重要。看下面分析。
4、哪些数据应该cache
      ajax中xmlhttp是默认传输器(dojo中用语)。如果浏览器支持,那么除了文件上传,几乎所有的功能xmlhttp都能实现,另外比起iframe等,xmlhttp是最好了。
  mimetype == "text/javascript"
  mimetype == "text/json"
  mimetype = "text/html"
  mimetype == "application/xml"
  mimetype: "text/plain"
不知道大家开发过程中用到哪几种”格式“,就cahce来说,我觉得text/plain最好了,简单的文本,但实际开发过程中,最常用的是xml和json,还有html代码段。
   就我知识来说,xml,json,html都可以进行cache,因为从类型上看来,它们都是数据,就象j2ee中的DTO一样,没有任何状态、逻辑,只包括数据。
   我想表达的意思是,如果你需要ajax cache,那么从服务器返回的数据无论格式怎么样,但不能包括任何状态、逻辑,只包括数据。
    例如dwr返回的数据其实是json,但没关系,因为它只是java DTO对象对JSON的转化,没有状态。这里需要注意,你不要改变Object.prototype对象,因为返回的是javascript 对象,如果你要cache对象,那么你不要修改这个对象的值,注意javascript与java对象一样,你得到的只是它的”句柄“。
5、cache key怎么设定
先看看dojo.io里面cache key的方法


function getCacheKey(url, query, method) {
   return url + "|" + query + "|" + method.toLowerCase();
}


如果你用dojo.io或YUI/prototype.js这些框架,估计这三个参数就OK了,但是query可能会长点,但是这类框架必须有servlet,或必须有struts/webwork之类的web表现层,增加了代码量,面对ajax开发人员的是一堆url和?key=value&key1=value1.

dwr类框架cache key设定:


Logic.method = function(p0, 01,callback) {
DWREngine._execute(Logic._path, 'Logic', 'method', p0,p1, callback);
}


就上面这个方法来说,CahceKey


function getCacheKey(Logic._path, 'Logic', 'method', p0,p1, callback) {
   return Logic._path+ "|" + Logic+ "|" + p0+ "|" +p1;
}


现在对于不同的callback可以用cache数据了。当然如果dwr支持cache,我们需要改写DWREngine._execute方法和DWREngine._handleResponse方法。由于代码我没测试过,但大致上应该可以。

6、如何应用cache呢
   cache当然只在query时才用,但如果你的应用修改数据,你必须把cache remove掉。说起来是个简单的问题,但具体应用起来比较复杂。
   在j2ee里面,有时我们用 find,get开头方法当成查询add cache,insert/update/delete开头的方法remove  cache.但实际写代码时,可能不全是增删改查,有很复杂的逻辑,个人还是倾向与手工的add cache和remove cache.
   在dojo.io中有个参数useCache: false,可以控制是否需要add cache。但dojo.io没有提供remove cache的API。不过这些工作得我们自己实现,如果removeAll cache就比较简单了,如果要remove(key) 就比较难实现了。
7、代码例子
仿照dojo我做了个测试代码,如下只能在FF下运行哦:
要运行以下代码,你必须建立个data.txt 放到这个htm同一目录下


<body>
<INPUT TYPE="button" value="use cache" onclick="io.bind({
   asyn : true,
url:'data.txt',
method :'GET',
useCache : true,
callback : log,
callbackObj : window
});">
<INPUT TYPE="button" value="not cache" onclick="io.bind({
   asyn : true,
url:'data.txt',
method :'GET',
useCache : false,
callback : log,
callbackObj : window
});">
<INPUT TYPE="button" value="clear cahce" onclick="io.clearCache();">
<div id="log"></div>

</body>
<SCRIPT LANGUAGE="JavaScript">
<!--
function log(msg){
document.getElementById('log').innerHTML+=msg+'<br>';
}
var io =new function(){
   var getHttp=function(){
     return new XMLHttpRequest();
};
function doLoad(callbackObj,callback,data,args){
       callback.apply(callbackObj,[data]);
       addCache(args,data);
};
var _cache={};
var getCacheKey=function(args){
       return args.url + args.method.toLowerCase();
}
var addCache=function(args,data){
       _cache[getCacheKey(args)]=data;
}
var getCahce=function(args){
       return _cache[getCacheKey(args)];
}
this.clearCache=function(){
     log('cache is empty!');
       _cache={};
}
this.bind=function(args){
   var cacheObj=getCahce(args);
   if(args.useCache&&cacheObj){
       log('cache is exist');
           doLoad(args.callbackObj,args.callback,cacheObj,args);
     return;
   }
   if(args.useCache)
           log('cache isn\'t exist');

       //cache
   var http=getHttp();
     http.open(args.method, args.url+'?iodate='+new Date(), args.asyn);
     if(args.asyn){
     var tempInterval=window.setInterval(
       function(){
       if(http.readyState==4){
       window.clearInterval(tempInterval);
       doLoad(args.callbackObj,args.callback,http.responseText,args);
       }
       }
      ,50) ;
   }
   http.send(null);
   if(!args.asyn){
       doLoad(args.callbackObj,args.callback,http.responseText,args);
   }
     return false;
};

};
//-->
</SCRIPT>


W 3 C h i n a ( since 2003 ) 旗 下 站 点
苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
46.875ms