离线存储 做为 html5 的一个特性在现代标准浏览器下已经被广泛实现,特别是 ie8 中也得以实现,但是对于目前仍然流行的ie6,7来说则需要一些额外的兼容性处理。
目前的各种数据存储方式:
1。cookie
cookie 可通过 domain= 设置 domain (必须为当前页面 hostname 的后缀《点分割》),默认为当前页面的 hostname。浏览器提交时通过当前页面的 hostname 和 cookie 的 domain 作比较,如果某个cookie 的 domain 是当前页面 hostname 的后缀则发送给服务器。
优点:
所有浏览器一致兼容
缺点:
不严格的离线存储,每次和服务器交互这些信息都会来回传递,浪费带宽。
每个域只能存储4kb,实际上是送到服务器的大小,多余截断但是仍然可以用脚本访问。
个数限制,根据浏览器不同大概 20-50 个。
数据必须为字符串格式
2.flash sharedObject
将 flash 插件作为数据存取空间 ,对于win7,文件实体化于:
c:\Users\用户名\AppData\Roaming\Macromedia\Flash Player\#SharedObjects\随机串\
默认每个域下100KB的存储空间 ( refer:YUI2 SWFStore ),用户也可以这里 设置。
经过用户许可,设置可获得无限的使用空间
updated 2011-04-28:
flash 域 和 cookie 域不同,cookie 域指的是页面所在 domain,而 flash 域则为该 flash 文件所在的页面的 hostname,flash 所在文件服务器可通过 crossdomain.xml 来允许哪些页面 hostname 可以操纵 flash 对象的存储数据,因此可实现cookie 不能的跨域共享数据。需要注意的是同个 hostname 下的多个 flash 实际上是共享默认 100K 的限制,而不是以文件为单元限额。
refer : sharedobject 介绍
优点:
所有浏览器一致兼容,
不会产生网络流量,
不受用户清空浏览器缓存影响,
不同浏览器间也可以共享数据。
通过设置可以不受域访问约束。
数据可以是 javascript 简单格式,例如数组,对象,字符串
理论上经过用户允许可获得无限的存储空间,例如 yui swfstore 当存储空间不足时,会触发 pending 事件,这时我们可以把改 flash 显示在页面中央。用户点击了允许后,则会存储空间扩容(4级 100k -> 1M -> 10M -> unlimited):
store.on("pending", function() { o.set("width", 215); o.center(); o.show(); // 轮训,直到用户允许 setTimeout(function() { store.retrySave(); }, 1000); });
缺点:
依赖于外部插件(flash)的安装
3.userData
每个应用可以产生上限64kb的单个xml数据文件,单个域可存储上限640k,对于xp,xml实体化于:
C:\Documents and Settings\用户名\UserData
优点:
不需要插件且不和服务器产生网络交互。
缺点:
ie 6,7 浏览器私有特性。
存储数据访问域控制过于严格,只能同样页面访问先前存储的数据。
存在由于内网安全设置导致的访问出错(属性未定义)。
4.localStorage
标准的本地存储解决方案,无限量的存储空间(ie8规定为单个 hostname 上限10MB),同一域内所有页面可互相访问。
以及更复杂完善,支持事务的数据库存储方案 。
updated 2010-11-10
ie8 的 localStorage 只能在 http 协议下使用,在 file 协议下(本地文件中):typeof localStorage 为 undefined
updated 2011-04-28
localStorage 的作用域限定于 html5 origin定义 ,即三元组:(scheme, host, port)。同一域名下的所有网页都共享同样的数据,这时就要注意命名冲突了。
优点:
适用当前以及未来的所有的标准浏览器
缺点:
目前流行的浏览器不能支持。
数据需要序列化为字符串, 否则会被自动 toString。这里还需要注意的是:ie (8,9) 性能并不好,大数据量序列化会造成假死现象,推荐还是使用 flash 解决方案:可以存储 plain javascript 格式,不需要序列化。
容量有限,虽然规范没有明确规定,但目前 支持的浏览器都是限额 5M ,而且不像 flash 解决方案一样可以经过程序申请而扩容,超过 5M ,则会抛出 QUOTA_EXCEEDED_ERR error !
兼容:
从上可见,flash具备最多的优点(基本上完全覆盖localStorage),而localStorage 则具备光明的前景,甚至可以采用具备完善事务支持的webdatabase,persistJS 综合考虑提供了完全的解决方案,可方便的在上述4种方法中进行切换,但是过于复杂,可能现实中根本用不到。
目前的最佳实践我认为则是通过 flash 来模拟不支持localstorage浏览器的本地存储:即创建flash为底层的localStorage ,对于连 flash 都不安装的 ie6,7用户就没有考虑的必要了。
Flash in ie note :
当 ie 下flash被缓存时,再次访问,flash 的 ready 事件会在 flash 添加到 dom 的瞬间同步触发,若利用桥接模式使用 javascript 对象封装flash ,则要注意修正,否则
1.ie 缓存状态下事件会在注册之前就触发了。(同步触发)
2.swf 刚 ready,在其事件处理函数中调用 swf其本身 的 External Interface 方法会
flash 内部出错。
比较好的方法则是,手动强制异步flash的事件触发:
FlashBridge.EventHandler = function(id, event) { var instance = instances[id]; if (instance) { //防止ie同步触发事件,后面还没on呢,另外给 swf 喘息机会 //否则同步后触发事件,立即调用swf方法会出错 setTimeout(function() { instance._eventHandler.call(instance, event); }, 100); } };
2010-09-25 update:
发现最新升级 firefox 下的 flash 插件似乎不鼓励单纯使用不可见 flash 做为后台数据支撑,当
1.flash设置为width,height=0
2.或其外围容器的宽高为0
3.或其外围容器定位到了视窗以外
都将导致flash不会触发ready事件,所以只能做到将外围容器设置宽高为1,overflow:hidden,定位到视窗内:
"<div style='width:1px;" + "height:1px;" + "position:absolute;" + //必须使创建的flash视窗内可见,才会触发contentReady "left:" + DOM.scrollLeft() + "px;" + "top:" + DOM.scrollTop() + "px;" + "overflow:hidden;'><object width='原宽度' ...>....</object></div>"