浏览器本地存储-localStorage && globalStorage || sessionStorage || UserData

浏览器的本地存储出来也有段时间了。Firefox 是从 2开始支持的,IE 似乎是从 8 才开始支持。 Google Chome 似乎暂时还不支持。

关于客户端存储的标准,可以参考这里:

http://www.whatwg.org/specs/web-apps/current-work/#scs-client-side

这一个存储是基于DOM的,也可以说是未来各个浏览器都会支持的一项功能。

浏览器客户端存储方式主要有四种:
1、 cookie
2、 flash shared object
3、 IE的 userdata
4、 DOM storage

我在 anehta 的水印系统中,使用的是第二种方式:FSO。
yahoo 在 安全印章系统中,还同时使用了 第三种,IE 的 userdata。 不过这个存储的地方在高版本的IE中好像支持不好。 所以未来的趋势肯定是利用 DOM storage。

DOM storage 分为两种, 一个是 叫做 sessionStorage,另一个叫做 localStorage,这是IE的叫法,在 Firefox 中叫做 globalStorage。(sessionStorage是FF,IE通用)

从名字就可以看出,sessionStorage是和当前窗口相关的,而localStorage 则是和当前窗口无关的,关了浏览器再开起来还会存在,还能读到。

对于 javascript 来说, dom storage 实际上就是一个数组。通过非常简单的API调用方式就能够使用DOM Storage。

设置一个值: window.sessionStorage.setItem(key, value);
读取一个值: window.sessionStorage.getItem(key);

还有其他API,可以参考相关手册。
浏览器本地存储-localStorage && globalStorage || sessionStorage || UserData_第1张图片

而 IE 的 localStorage 和 FF的 globalStorage 还是有差别的.

globalStorage 有区分域。

window.globalStorage.namedItem(domain).setItem(key, value);

通过 namedItem 可以设置域,跨域的访问在FF出会抛出一个安全错误的异常。

FF 的 globalStorage 是使用  SQLite 的方式来存储的。每个域下都有5M的空间,远远大于cookie能存储的值。

前段时间,gmail 的iphone版好像开始存储数据到 localStorage 中,我的博客中也曾经 记载这个事情。有安全专家曾担心可能会出现一些对该storage的注射,还需要深度挖掘下利用方式。

我们知道,XSS Payload 实际上也可以看成是一个javascript的应用,所以使用 DOM Storage ,在XSS中也会起到一些更好的用户体验。

其中最主要的一个作用就是 跨页面传递数据

无论是sessionStorage 还是 localStorage,都能够起到这个作用。

对于这一点,luoluo在 webzine0x03 中有一篇文章提到了一些tips。那么,现在又多了一种方法了!不同于window对象的是,localStorage是不依赖于当前窗口的!

不同于cookie,  localStorage 是用户清理了cookie之后还存在的,一般是没有 expire 时间的,应该会比较好用。


为了方便有兴趣的朋友继续研究,整理一些参考资料如下:

http://www.niallkennedy.com/blog/2007/01/ajax-performance-local-storage.html

http://ajaxian.com/archives/firefox-2-client-side-storage-and-a-lot-more

https://developer.mozilla.org/en/Storage

http://ejohn.org/blog/dom-storage/

http://www.xul.fr/en/html5/sessionstorage.php



I was a tad disappointed when I found out that localStorage only supports storing strings, since I was hoping for something more structured. But withnative JSON support it’s easy to create an object store on top of localStorage:

Storage.prototype.setObject = function(key, value) {
    this.setItem(key, JSON.stringify(value));
}
 
Storage.prototype.getObject = function(key) {
    return JSON.parse(this.getItem(key));
}

localStorage databases are scoped to an HTML5 origin, basically the tuple(scheme, host, port). This means that the database is shared across all pages on the same domain, even concurrently by multiple browser tabs. However, a page connecting over http:// cannot see a database that was created during an https:// session.

localStorage and sessionStorage are supported by Firefox 3.5, Safari 4.0, and IE8. You can find more compatibility details on quirksmode.org, including more detail on the storage event.


//下面将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。

容量

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

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类,这样可以更方便地使用UserData,代码如下:

/** @class 定义userdata的操作 */
    var UserData = {
    // 定义userdata对象
    o : null,
    // 设置文件过期时间
    defExps : 365,
    // 初始化userdate对象
    init : function(){
        if(!UserData.o){
           try{
                UserData.o = document.createElement('input');
                UserData.o.type = "hidden";
                //UserData.o.style.behavior = "url('#default#userData')" ;
                UserData.o.addBehavior ("#default#userData");
                document.body.appendChild(UserData.o);
            }catch(e){
                return false;
            }
        };
        return true;
    },
    // 保存文件到userdata文件夹中 f-文件名,c-文件内容,e-过期时间
    save : function(f, c, e){
        if(UserData.init()){
            var o = UserData.o;      
            // 保持对象的一致
            o.load(f);   
            // 将传入的内容当作属性存储
            if(c) o.setAttribute("code", c);     
            // 设置文件过期时间
            var d = new Date(), e = (arguments.length == 3) ? e : UserData.defExps;
            d.setDate(d.getDate()+e);
            o.expires = d.toUTCString();        
            // 存储为制定的文件名
            o.save(f);
        }
    }, 
    // 从uerdata文件夹中读取指定文件,并以字符串形式返回。f-文件名
    load : function(f){
        if(UserData.init()){
            var o = UserData.o;
            // 读取文件
            o.load(f);       
            // 返回文件内容
            return o.getAttribute("code");
        }
    },
    // 检查userdata文件是否存在 f-文件名
    exist : function(f){
        return UserData.load(f) != null;
    },
    // 删除userdata文件夹中的指定文件 f-文件名
    remove : function(f){
        UserData.save(f, false, -UserData.defExps);
    }
    // UserData函数定义结束
};

参考资料:

自:http://hi.baidu.com/aullik5/blog/item/60d2b5fc52675a1e09244d77.html

自:http://www.cnblogs.com/QLeelulu/archive/2008/03/29/1129322.html

你可能感兴趣的:(浏览器本地存储-localStorage && globalStorage || sessionStorage || UserData)