常用浏览器本地存储的几种方案对比
有时需要将网页中的一些数据保存在浏览器端,这样做的好处是,当下次访问页面时,不需要再次向服务器请求数据,直接就可以从本地读取数据。目前常用的有以下几种方法:
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();
};
});