常用浏览器本地存储的几种方案对比
有时需要将网页中的一些数据保存在浏览器端,这样做的好处是,当下次访问页面时,不需要再次向服务器请求数据,直接就可以从本地读取数据。目前常用的有以下几种方法:
cookie
cookie会随着每次HTTP请求头信息一起发送,无形中增加了网络流量,另外,cookie能存储的数据容量有限,根据浏览器类型不同而不同,IE6大约只能存储2K。
Flash ShareObject
这种方式能能解决上面提到的cookie存储的两个弊端,而且能够跨浏览器,应该说是目前最好的本地存储方案。不过,需要在页面中插入一个Flash,当浏览器没有安装Flash控件时就不能用了。所幸的是,没有安装Flash的用户极少。
缺点:需要安装Flash插件。
Google Gear
Google开发出的一种本地存储技术。
缺点:需要安装Gear组件。
userData
IE浏览器可以使用userData来存储数据,容量可达到640K,这种方案是很可靠的,不需要安装额外的插件。缺点:它仅在IE下有效。
sessionStorage
使用于Firefox2+的火狐浏览器,用这种方式存储的数据仅窗口级别有效,同一个窗口(或者Tab)页面刷新或者跳转,都能获取到本地存储的数据,当新开窗口或者页面时,原来的数据就失效了。
缺点:IE不支持、不能实现数据的持久保存。
globalStorage
使用于Firefox2+的火狐浏览器,类似于IE的userData。
//赋值 globalStorage[location.hostname]['name'] = 'tugai'; //读取 globalStorage[location.hostname]['name']; //删除 globalStorage[location.hostname].removeItem('name');
缺点:IE不支持。
localStorage
localStorage是Web Storage互联网存储规范中的一部分,现在在Firefox 3.5、Safari 4和IE8中得到支持。
缺点:低版本浏览器不支持。
结论:
Flash shareobject是不错的选择,如果你不想在页面上嵌入Flash,可以结合使用userData(IE6+)和globalStorage(Firefox2+)和localStorage(chrome3+)实现跨浏览器。
补充:由于项目需要,简单模拟了HTML5 localStorage中的几个方法,支持firefox2+,IE5+,chrome3+,其他不详。
if (!('localStorage' in window)) { window.localStorage = (function() { var documentElement, isIE = !!document.all; if (isIE) { documentElement = document.documentElement; documentElement.addBehavior('#default#userdata'); } return { setItem: function(key, value) { if (isIE) { documentElement.setAttribute('value', value); documentElement.save(key); } else { window.globalStorage[location.hostname][key] = value; } }, getItem: function(key) { if (isIE) { documentElement.load(key); return documentElement.getAttribute('value'); } return window.globalStorage[location.hostname][key]; }, removeItem: function(key) { if (isIE) { documentElement.removeAttribute('value'); documentElement.save(key); } else { window.globalStorage[location.hostname].removeItem(key); } } }; })(); } //写入 localStorage.setItem('name', 'shuiniuer'); //读取 localStorage.getItem('name'); //删除 localStorage.removeItem('name');
封装了一个插件
/** * 客户端的本地存储组件. * * 注意:当客户端发起HTTP请求时,存储的数据,不会传递给服务器端,和Cookie不同. * * 》使用到的技术特性: * 1. localStorage(支持:IE8+、FF3.5+、Chrome4+、Safari4+、Opera10.5+) * 2. sessionStorage(支持:IE8+、FF3.5+、Chrome4+、Safari4+、Opera10.5+) * 3. userData,IE专有特性,最大存储容量为640K(在IE6、IE7下使用) * * 》持久存储API: * var Local = require('storage').Local; * 1. Local.read(name) // 读取 * 2. Local.save(name, value) // 保存 * 3. Local.remove(name) // 删除 * var __newVar__20130529151132107000 = ; * 》会话存储API(关闭浏览器后,数据自动删除):__newVar__20130529151132107000 * var Session = require('storage').Session; * 1. Session.read(name) // 读取 * 2. Session.save(name, value) // 保存 * 3. Session.remove(name) // 删除 * * @author 水牛儿 * @version 2013/5/28 */ define(function(require, exports, module){ var $ = require('jquery'); // IE UserData特性 var UserData = function(sname){ this.sname = sname; this.tname = sname + '_names'; this.isSession = sname.split('_')[0] === 'session'; this.init(); }; UserData.prototype = { init: function(){ if (this.isSession) { this.names = this.getItem(this.tname) || ''; this.restore(); } }, eStore: function(){ return $('<span class="jxc-ie-userdata"/>').appendTo(document.body)[0]; }(), getItem: function(name){ this.eStore.load(this.sname); return this.eStore.getAttribute(name); }, setItem: function(name, value){ this.addName(name); this.eStore.expires = getUTCString('3y'); this.eStore.setAttribute(name, value); this.eStore.save(this.sname); }, removeItem: function(name){ this.delName(name); this.eStore.removeAttribute(name); this.eStore.save(this.sname); }, // 临时存储,要想刷新页面,不清除数据,那么每条数据都必须重新设置下 // 直接改过期日期还不行,我x,太变态了,why? restore: function(){ if (this.names) { var names = this.names.split(' '), eStore = this.eStore; eStore.load(this.sname); eStore.expires = getUTCString('3y'); for (var i = 0, name; name = names[i]; i++) { eStore.setAttribute(name, eStore.getAttribute(name)); } eStore.save(this.sname); } }, addName: function(name){ if (this.isSession) { name += ' '; if (this.names.indexOf(name) < 0) { this.names += name; this.eStore.setAttribute(this.tname, this.names); } } }, delName: function(name){ if (this.isSession) { this.names = this.names.replace(name + ' ', ''); this.eStore.setAttribute(this.tname, this.names); } }, // 刷新页面时,设置5s作为缓冲时间,这期间完成数据恢复 // 如果关闭浏览器,5s没有重新打开页面,那么数据就失效了 clear: function(){ this.eStore.expires = getUTCString('5s'); this.eStore.save(this.sname); } }; /** * 持久化存储. */ exports.Local = function(){ var oStore = window.localStorage; if (!oStore) { oStore = new UserData('local_' + location.hostname); } return { read: bind(oStore.getItem, oStore), save: bind(oStore.setItem, oStore), remove: bind(oStore.removeItem, oStore) }; }(); /** * 临时存储. */ exports.Session = function(){ var oStore = window.sessionStorage; if (!oStore) { oStore = new UserData('session_' + location.hostname); addUnloadEvent(oStore); } return { read: bind(oStore.getItem, oStore), save: bind(oStore.setItem, oStore), remove: bind(oStore.removeItem, oStore) }; }(); // 绑定函数的this对象 function bind(fn, context) { return function(){ return fn.apply(context, arguments); }; }; // 窗口关闭时,清除userdata,但刷新不清除 function addUnloadEvent(oStore) { window.attachEvent('onunload', function(){ window.detachEvent('onunload', arguments.callee); oStore.clear(); }); }; // expires = number + y|M|d|h|m|s // expires = 360d // 360天 function getUTCString(expires) { expires += ''; var a = /([^yMdhms]+)(\w)?/.exec(expires), n = a ? a[1] : 0, f = a ? a[2] : 'y'; switch (f) { case 'y': n*=365*24*3600*1000; break; case 'M': n*=30*24*3600*1000; break; case 'd': n*=24*3600*1000; break; case 'h': n*=3600*1000; break; case 'm': n*=60*1000; break; case 's': n*=1000; break; default: n*=1000; break; } var d = new Date(); d.setMilliseconds( d.getMilliseconds() + n ); return d.toUTCString(); }; });