UserData使用总结 收藏
前一段时间做一个在线订单系统,因为有好几项服务可供选择,要求在选每一种服务后进入下一步,在操作过程中还可以通过上一步来回到上一次的服务选购里重新下订,每一个种服务都有好多选项可选,整个过程中有较大的数据量要临时存储,

现在最流行的本地存储莫过于 cookie 的应用,但 浏览器对cookie有很多限制 ,最大的限制在于其对cookie 总大小,仅为 4K 左右(包括名(name)、值(value)和等号)。

对于复杂一点的应用和需求,仅有的 4K 大小还是有点相形见绌,其实很多浏览器(IE、Firefox、Safari)本身也提供了自己的本地存储的功能,或许在特定的环境下能满足我们。因此自己通过学习整理,写了一个userData的简单操作类。

应用范围
UserData是微软为IE专门在系统中开辟的一块存储空间,所以说只支持Windows+IE的组合,实际测试在2000(IE5.5)、XP(IE6、IE7),Vista(IE7)下都是可以正常使用的。

在哪儿?
在XP下,一般位于C:\Documents and Settings\用户名\UserData,有些时候会在C:\Documents and Settings\用户名\Application Data\Microsoft\Internet Explorer\UserData。

在Vista下,位于C:\Users\用户名\AppData\Roaming\Microsoft\Internet Explorer\UserData。


从安全方面考虑,一个 userData 存储区只能用于同一目录和对同一协议进行存储。
如果使用 userData behavior 不正确可能会对你的应用造成危害,userData 存储区中的数据没有加密因而不安全的。任何可以访问 UserData 保存磁盘的应用都可以访问该数据,所以,推荐不要保存敏感的数据,比如信用卡号,详细:《Security Considerations: DHTML and Default Behaviors》
userData behavior 会跨 session 存储信息到存储区,这提供了动态的数据结构和比 cookie(一般 4KB) 更大的容量。userData 存储区的容量依赖于 domain 的安全域。下表显示的是 userData 存储最大容量,对单独文档和整个域名的所有文档都适用,但基于安全域。
如果设置 userData behavior 到 html、head、title 或者 style 对象上,当 save 和 load 方法被调用时会出错。如果必须设置到 style 中,可以设置内联或者文档头,例如:
<style>
    .storeuserData {behavior:url(#default#userData);}
</style>
对于 userData behavior 来说 ID 是可选的,但是如果有,则会改善执行性能。
userData 可以将数据以 XML 格式保存在客户端计算机上,一般保存在 C(WIN 系统盘):/Documents and Settings/XXX/UserData/ 文件夹下。
userData 数据一直存在,除非人为删除或者用脚本设置该数据的失效日期(expires)。

容量
网页制作完成手册中这样说:

Security Zone
 Document Limit (KB)
 Domain Limit (KB)
 
Local Machine
 128
 1024
 
Intranet
 512
 10240
 
Trusted Sites
 128
 1024
 
Internet
 128
 1024
 
Restricted
 64
 640
 


线上使用时,单个文件的大小限制是128KB,一个域名下总共可以保存1024KB的文件,文件个数应该没有限制。在受限站点里这两个值分别是64KB和640KB,所以如果考虑到各种情况的话,单个文件最好能控制64KB以下。

如何使用?
用下面的JS语句就可以建立一个支持UserData的对象:

o = document.createElement('input');
o.type = "hidden";
o.addBehavior ("#default#userData");
//UserData.o.style.behavior = "url('#default#userData')" ;
//上面的语句也是一样的作用
document.body.appendChild(o);

说白了UserData就是样式里的一个Behavior,所以这样写也是一样的:

<input type=hidden class= storeuserData />
<style>
.storeuserData {behavior:url(#default#userData);}
</style>

UserData可以绑定在大多数的html标签上,具体为:

A, ACRONYM, ADDRESS, AREA, B, BIG, BLOCKQUOTE, BUTTON, CAPTION, CENTER, CITE, CODE, DD, DEL, DFN, DIR, DIV, DL, DT, EM, FONT, FORM, hn, HR, I, IMG, INPUT type=button, INPUT type=checkbox, INPUT type=file, INPUT type=hidden, INPUT type=image, INPUT type=password, INPUT type=radio, INPUT type=reset, INPUT type=submit, INPUT type=text, KBD, LABEL, LI, LISTING, MAP, MARQUEE, MENU, OBJECT, OL, OPTION, P, PLAINTEXT, PRE, Q, S, SAMP, SELECT, SMALL, SPAN, STRIKE, STRONG, SUB, SUP, TABLE, TEXTAREA, TT, U, UL, VAR, XM

UserData对象有以下的属性和方法:

属性
 描述
 
expires
 设置或读取文件过期时间
 
XMLDocument
 读取文件的XML DOM
 
方法
 描述
 
getAttribute
 读取指定属性的值
 
load
 打开文件
 
removeAttribute
 删除指定的属性
 
save
 保存文件
 
setAttribute
 为指定属性赋值
 


UserData文件实际上就是一个XML文件,通过文件名->属性的方式保存字符串,如以下一段代码:

o.setAttribute("code", "hello world!");
o.save("baidu");

    执行后,UserData文件夹中会生成一个baidu[1].xml文件,其中的内容是:
<ROOTSTUB code="hello,world!"/>

UserData类

view plaincopy to clipboardprint?
function behaviorUserdata(udObj)  
{  
    var me = this;  
    var loaded = '';    //当前已载入的文件名  
      
    this.udObj = getObject(udObj);  
    this.udObj.style.behavior = 'url(#default#userdata)';  
    this.value = this.udObj.value;  
    this.inhtml = this.udObj.innerHTML;  
      
    //检查文件是否存在,存在est=undefined并返回true否则返回false  
    this.exist = function(filename){  
        try{  
            me.udObj.load(filename);//将文件名为 filename的 XML 载入  
            me.loaded = filename;  
            return true;  
        }catch(e){ return false;}          
    }  
    //预加载  
    this.preLoad = function(filename){  
        if(me.loaded=='' || me.loaded!=filename){me.exist(filename);}  
        return me.loaded;  
    }  
    //获取指定的属性值  
    this.getAtrib = function(filename,atrib){  
        if(me.preLoad(filename)!='')  
        {  
            var val = me.udObj.getAttribute(atrib);  
            return val==null?"":val;  
        }return "";  
    }  
    //移除对象的指定属性  
    this.remAtrib = function(filename,atrib){  
        me.udObj.removeAttribute(atrib);  
        me.udObj.save(filename);    //将对象数据保存到名为filename的XML文件里面  
        return true;  
    }  
    //设置指定的属性值  
    this.setAtrib = function(filename,atrib,val,expire){  
        var etime = typeof(expire)=="undefined"?24*60*60:expire;  
        me.udObj.expires = me.setExpire(etime);  
        me.udObj.setAttribute(atrib,val);  
        me.udObj.save(filename);  
    }  
    //设置一个系列的对象数据(即整个XML文件)失效  
    this.remPartion = function(filename){  
        if(me.exist(filename))  
        {  
            me.udObj.expires = me.setExpire(-1);  
            me.udObj.save(filename);  
        }  
    }  
    //设置有效期  
    this.setExpire = function(sec){  
        var oTimeNow = new Date();  
        oTimeNow.setSeconds(oTimeNow.getSeconds() + parseInt(sec));  
        return oTimeNow.toUTCString();  
    }  

function behaviorUserdata(udObj)
{
 var me = this;
 var loaded = ''; //当前已载入的文件名
 
 this.udObj = getObject(udObj);
 this.udObj.style.behavior = 'url(#default#userdata)';
 this.value = this.udObj.value;
 this.inhtml = this.udObj.innerHTML;
 
 //检查文件是否存在,存在est=undefined并返回true否则返回false
 this.exist = function(filename){
  try{
   me.udObj.load(filename);//将文件名为 filename的 XML 载入
   me.loaded = filename;
   return true;
  }catch(e){ return false;}       
    }
 //预加载
 this.preLoad = function(filename){
  if(me.loaded=='' || me.loaded!=filename){me.exist(filename);}
  return me.loaded;
 }
 //获取指定的属性值
 this.getAtrib = function(filename,atrib){
  if(me.preLoad(filename)!='')
  {
   var val = me.udObj.getAttribute(atrib);
   return val==null?"":val;
  }return "";
 }
 //移除对象的指定属性
 this.remAtrib = function(filename,atrib){
  me.udObj.removeAttribute(atrib);
  me.udObj.save(filename); //将对象数据保存到名为filename的XML文件里面
  return true;
 }
 //设置指定的属性值
 this.setAtrib = function(filename,atrib,val,expire){
  var etime = typeof(expire)=="undefined"?24*60*60:expire;
  me.udObj.expires = me.setExpire(etime);
  me.udObj.setAttribute(atrib,val);
  me.udObj.save(filename);
 }
 //设置一个系列的对象数据(即整个XML文件)失效
 this.remPartion = function(filename){
  if(me.exist(filename))
  {
   me.udObj.expires = me.setExpire(-1);
   me.udObj.save(filename);
  }
 }
 //设置有效期
 this.setExpire = function(sec){
  var oTimeNow = new Date();
  oTimeNow.setSeconds(oTimeNow.getSeconds() + parseInt(sec));
  return oTimeNow.toUTCString();
 }
}