PersistJS

官网:http://pablotron.org/software/persist-js/

GitHub:https://github.com/jeremydurham/persist-js

PersistJS是一个在客户端进行数据存储的JavaScript框架。这种存储主要针对的是那些可以离线运行的Web 应用程序。与其它客户端存储框架相比,PersistJS有一些优点。

为什么不只使用cookie?

一直以来,Cookie是客户端存储技术中的传统解决方法。然而,相对于像PersistJS这样越来越流行的框架来说,使用cookie还是有一些不好 的地方。比如,cookie被限制在4k字节内。在每个HTTP处理中都要发送cookie会浪费带宽,而且在cookie的创建和修改也都比较复杂。

是什么让PersistJS更好?

  • 很小(gzip压缩之后只有3k)
  • API一致,与所用浏览器无关
  • 无须浏览器插件和其它库
  • 当所用浏览器不支持时,会退而使用cookie
  • 声称支持IE、Firefox和Safari的新版本
PersistJS也采用兼容性测试的策略,而没有采用浏览器测试。也就是说,并不是去检查是否支持某一特定版本的IE浏览器,而是去检查在所用IE的版 本中是否对所用到的每个调用进行支持。 例如,对某个特定调用未能进行支持的浏览器,不一定会立刻被拒绝。

用法示例

在客户端存储中保存数据就像下面的代码一样简单:
var store = new Persist.Store('My Data Store');
var data = "some arbitrary data of varying length";
store.set('saved_data', data);
查看数据需要回调函数,但也非常简单:
store.get('saved_data', function(ok, val) {
  if (ok) alert('saved data = ' + val);
});

PersistJS 中对文件名称的过滤:

采用正则

/^[a-z][a-z0-9_ \-]+$/i



附persist-min.js

(function () {
	if (window.google && google.gears) {
		return;
	}
	var F = null;
	if (typeof GearsFactory != 'undefined') {
		F = new GearsFactory();
	} else {
		try {
			F = new ActiveXObject('Gears.Factory');
			if (F.getBuildInfo().indexOf('ie_mobile') != -1) {
				F.privateSetGlobalObject(this);
			}
		} catch (e) {
			if ((typeof navigator.mimeTypes != 'undefined') && navigator.mimeTypes["application/x-googlegears"]) {
				F = document.createElement("object");
				F.style.display = "none";
				F.width = 0;
				F.height = 0;
				F.type = "application/x-googlegears";
				document.documentElement.appendChild(F);
			}
		}
	}
	if (!F) {
		return;
	}
	if (!window.google) {
		google = {};
	}
	if (!google.gears) {
		google.gears = {
			factory : F
		};
	}
})();
Persist = (function () {
	var VERSION = '0.3.1',
	P,
	B,
	esc,
	init,
	empty,
	ec;
	ec = (function () {
		var EPOCH = 'Thu, 01-Jan-1970 00:00:01 GMT',
		RATIO = 1000 * 60 * 60 * 24,
		KEYS = ['expires', 'path', 'domain'],
		esc = escape,
		un = unescape,
		doc = document,
		me;
		var get_now = function () {
			var r = new Date();
			r.setTime(r.getTime());
			return r;
		};
		var cookify = function (c_key, c_val) {
			var i,
			key,
			val,
			r = [],
			opt = (arguments.length > 2) ? arguments[2] : {};
			r.push(esc(c_key) + '=' + esc(c_val));
			for (var idx = 0; idx < KEYS.length; idx++) {
				key = KEYS[idx];
				val = opt[key];
				if (val) {
					r.push(key + '=' + val);
				}
			}
			if (opt.secure) {
				r.push('secure');
			}
			return r.join('; ');
		};
		var alive = function () {
			var k = '__EC_TEST__',
			v = new Date();
			v = v.toGMTString();
			this.set(k, v);
			this.enabled = (this.remove(k) == v);
			return this.enabled;
		};
		me = {
			set : function (key, val) {
				var opt = (arguments.length > 2) ? arguments[2] : {},
				now = get_now(),
				expire_at,
				cfg = {};
				if (opt.expires) {
					var expires = opt.expires * RATIO;
					cfg.expires = new Date(now.getTime() + expires);
					cfg.expires = cfg.expires.toGMTString();
				}
				var keys = ['path', 'domain', 'secure'];
				for (var i = 0; i < keys.length; i++) {
					if (opt[keys[i]]) {
						cfg[keys[i]] = opt[keys[i]];
					}
				}
				var r = cookify(key, val, cfg);
				doc.cookie = r;
				return val;
			},
			has : function (key) {
				key = esc(key);
				var c = doc.cookie,
				ofs = c.indexOf(key + '='),
				len = ofs + key.length + 1,
				sub = c.substring(0, key.length);
				return ((!ofs && key != sub) || ofs < 0) ? false : true;
			},
			get : function (key) {
				key = esc(key);
				var c = doc.cookie,
				ofs = c.indexOf(key + '='),
				len = ofs + key.length + 1,
				sub = c.substring(0, key.length),
				end;
				if ((!ofs && key != sub) || ofs < 0) {
					return null;
				}
				end = c.indexOf(';', len);
				if (end < 0) {
					end = c.length;
				}
				return un(c.substring(len, end));
			},
			remove : function (k) {
				var r = me.get(k),
				opt = {
					expires : EPOCH
				};
				doc.cookie = cookify(k, '', opt);
				return r;
			},
			keys : function () {
				var c = doc.cookie,
				ps = c.split('; '),
				i,
				p,
				r = [];
				for (var idx = 0; idx < ps.length; idx++) {
					p = ps[idx].split('=');
					r.push(un(p[0]));
				}
				return r;
			},
			all : function () {
				var c = doc.cookie,
				ps = c.split('; '),
				i,
				p,
				r = [];
				for (var idx = 0; idx < ps.length; idx++) {
					p = ps[idx].split('=');
					r.push([un(p[0]), un(p[1])]);
				}
				return r;
			},
			version : '0.2.1',
			enabled : false
		};
		me.enabled = alive.call(me);
		return me;
	}
		());
	var index_of = (function () {
		if (Array.prototype.indexOf) {
			return function (ary, val) {
				return Array.prototype.indexOf.call(ary, val);
			};
		} else {
			return function (ary, val) {
				var i,
				l;
				for (var idx = 0, len = ary.length; idx < len; idx++) {
					if (ary[idx] == val) {
						return idx;
					}
				}
				return -1;
			};
		}
	})();
	empty = function () {};
	esc = function (str) {
		return 'PS' + str.replace(/_/g, '__').replace(/ /g, '_s');
	};
	var C = {
		search_order : ['localstorage', 'globalstorage', 'gears', 'cookie', 'ie', 'flash'],
		name_re : /^[a-z][a-z0-9_ \-]+$/i,
		methods : ['init', 'get', 'set', 'remove', 'load', 'save', 'iterate'],
		sql : {
			version : '1',
			create : "CREATE TABLE IF NOT EXISTS persist_data (k TEXT UNIQUE NOT NULL PRIMARY KEY, v TEXT NOT NULL)",
			get : "SELECT v FROM persist_data WHERE k = ?",
			set : "INSERT INTO persist_data(k, v) VALUES (?, ?)",
			remove : "DELETE FROM persist_data WHERE k = ?",
			keys : "SELECT * FROM persist_data"
		},
		flash : {
			div_id : '_persist_flash_wrap',
			id : '_persist_flash',
			path : 'persist.swf',
			size : {
				w : 1,
				h : 1
			},
			params : {
				autostart : true
			}
		}
	};
	B = {
		gears : {
			size : -1,
			test : function () {
				return (window.google && window.google.gears) ? true : false;
			},
			methods : {
				init : function () {
					var db;
					db = this.db = google.gears.factory.create('beta.database');
					db.open(esc(this.name));
					db.execute(C.sql.create).close();
				},
				get : function (key) {
					var r,
					sql = C.sql.get;
					var db = this.db;
					var ret;
					db.execute('BEGIN').close();
					r = db.execute(sql, [key]);
					ret = r.isValidRow() ? r.field(0) : null;
					r.close();
					db.execute('COMMIT').close();
					return ret;
				},
				set : function (key, val) {
					var rm_sql = C.sql.remove,
					sql = C.sql.set,
					r;
					var db = this.db;
					var ret;
					db.execute('BEGIN').close();
					db.execute(rm_sql, [key]).close();
					db.execute(sql, [key, val]).close();
					db.execute('COMMIT').close();
					return val;
				},
				remove : function (key) {
					var get_sql = C.sql.get,
					sql = C.sql.remove,
					r,
					val = null,
					is_valid = false;
					var db = this.db;
					db.execute('BEGIN').close();
					db.execute(sql, [key]).close();
					db.execute('COMMIT').close();
					return true;
				},
				iterate : function (fn, scope) {
					var key_sql = C.sql.keys;
					var r;
					var db = this.db;
					r = db.execute(key_sql);
					while (r.isValidRow()) {
						fn.call(scope || this, r.field(0), r.field(1));
						r.next();
					}
					r.close();
				}
			}
		},
		globalstorage : {
			size : 5 * 1024 * 1024,
			test : function () {
				if (window.globalStorage) {
					var domain = '127.0.0.1';
					if (this.o && this.o.domain) {
						domain = this.o.domain;
					}
					try {
						var dontcare = globalStorage[domain];
						return true;
					} catch (e) {
						if (window.console && window.console.warn) {
							console.warn("globalStorage exists, but couldn't use it because your browser is running on domain:", domain);
						}
						return false;
					}
				} else {
					return false;
				}
			},
			methods : {
				key : function (key) {
					return esc(this.name) + esc(key);
				},
				init : function () {
					this.store = globalStorage[this.o.domain];
				},
				get : function (key) {
					key = this.key(key);
					return this.store.getItem(key);
				},
				set : function (key, val) {
					key = this.key(key);
					this.store.setItem(key, val);
					return val;
				},
				remove : function (key) {
					var val;
					key = this.key(key);
					val = this.store.getItem[key];
					this.store.removeItem(key);
					return val;
				}
			}
		},
		localstorage : {
			size : -1,
			test : function () {
				try {
					if (window.localStorage && window.localStorage.setItem("test", null) == undefined) {
						if (/Firefox[\/\s](\d+\.\d+)/.test(navigator.userAgent)) {
							var ffVersion = RegExp.$1;
							if (ffVersion >= 9) {
								return true;
							}
							if (window.location.protocol == 'file:') {
								return false;
							}
						} else {
							return true;
						}
					} else {
						return false;
					}
					return window.localStorage ? true : false;
				} catch (e) {
					return false;
				}
			},
			methods : {
				key : function (key) {
					return this.name + '>' + key;
				},
				init : function () {
					this.store = localStorage;
				},
				get : function (key) {
					key = this.key(key);
					return this.store.getItem(key);
				},
				set : function (key, val) {
					key = this.key(key);
					this.store.setItem(key, val);
					return val;
				},
				remove : function (key) {
					var val;
					key = this.key(key);
					val = this.store.getItem(key);
					this.store.removeItem(key);
					return val;
				},
				iterate : function (fn, scope) {
					var l = this.store,
					key,
					keys;
					for (var i = 0; i < l.length; i++) {
						key = l.key(i);
						keys = key.split('>');
						if ((keys.length == 2) && (keys[0] == this.name)) {
							fn.call(scope || this, keys[1], l.getItem(key));
						}
					}
				}
			}
		},
		ie : {
			prefix : '_persist_data-',
			size : 64 * 1024,
			test : function () {
				return window.ActiveXObject ? true : false;
			},
			make_userdata : function (id) {
				var el = document.createElement('div');
				el.id = id;
				el.style.display = 'none';
				el.addBehavior('#default#userdata');
				document.body.appendChild(el);
				return el;
			},
			methods : {
				init : function () {
					var id = B.ie.prefix + esc(this.name);
					this.el = B.ie.make_userdata(id);
					if (this.o.defer) {
						this.load();
					}
				},
				get : function (key) {
					var val;
					key = esc(key);
					if (!this.o.defer) {
						this.load();
					}
					val = this.el.getAttribute(key);
					return val;
				},
				set : function (key, val) {
					key = esc(key);
					this.el.setAttribute(key, val);
					if (!this.o.defer) {
						this.save();
					}
					return val;
				},
				remove : function (key) {
					var val;
					key = esc(key);
					if (!this.o.defer) {
						this.load();
					}
					val = this.el.getAttribute(key);
					this.el.removeAttribute(key);
					if (!this.o.defer) {
						this.save();
					}
					return val;
				},
				load : function () {
					this.el.load(esc(this.name));
				},
				save : function () {
					this.el.save(esc(this.name));
				}
			}
		},
		cookie : {
			delim : ':',
			size : 4000,
			test : function () {
				return P.Cookie.enabled ? true : false;
			},
			methods : {
				key : function (key) {
					return this.name + B.cookie.delim + key;
				},
				get : function (key, fn) {
					var val;
					key = this.key(key);
					val = ec.get(key);
					return val;
				},
				set : function (key, val, fn) {
					key = this.key(key);
					ec.set(key, val, this.o);
					return val;
				},
				remove : function (key, val) {
					var val;
					key = this.key(key);
					val = ec.remove(key);
					return val;
				}
			}
		},
		flash : {
			test : function () {
				try {
					if (!swfobject) {
						return false;
					}
				} catch (e) {
					return false;
				}
				var major = swfobject.getFlashPlayerVersion().major;
				return (major >= 8) ? true : false;
			},
			methods : {
				init : function () {
					if (!B.flash.el) {
						var key,
						el,
						fel,
						cfg = C.flash;
						el = document.createElement('div');
						el.id = cfg.div_id;
						fel = document.createElement('div');
						fel.id = cfg.id;
						el.appendChild(fel);
						document.body.appendChild(el);
						B.flash.el = swfobject.createSWF({
								id : cfg.id,
								data : this.o.swf_path || cfg.path,
								width : cfg.size.w,
								height : cfg.size.h
							}, cfg.params, cfg.id);
					}
					this.el = B.flash.el;
				},
				get : function (key) {
					var val;
					key = esc(key);
					val = this.el.get(this.name, key);
					return val;
				},
				set : function (key, val) {
					var old_val;
					key = esc(key);
					old_val = this.el.set(this.name, key, val);
					return old_val;
				},
				remove : function (key) {
					var val;
					key = esc(key);
					val = this.el.remove(this.name, key);
					return val;
				}
			}
		}
	};
	init = function () {
		var i,
		l,
		b,
		key,
		fns = C.methods,
		keys = C.search_order;
		for (var idx = 0, len = fns.length; idx < len; idx++) {
			P.Store.prototype[fns[idx]] = empty;
		}
		P.type = null;
		P.size = -1;
		for (var idx2 = 0, len2 = keys.length; !P.type && idx2 < len2; idx2++) {
			b = B[keys[idx2]];
			if (b.test()) {
				P.type = keys[idx2];
				P.size = b.size;
				for (key in b.methods) {
					P.Store.prototype[key] = b.methods[key];
				}
			}
		}
		P._init = true;
	};
	P = {
		VERSION : VERSION,
		type : null,
		size : 0,
		add : function (o) {
			B[o.id] = o;
			C.search_order = [o.id].concat(C.search_order);
			init();
		},
		remove : function (id) {
			var ofs = index_of(C.search_order, id);
			if (ofs < 0) {
				return;
			}
			C.search_order.splice(ofs, 1);
			delete B[id];
			init();
		},
		Cookie : ec,
		Store : function (name, o) {
			if (!C.name_re.exec(name)) {
				throw new Error("Invalid name");
			}
			if (!P.type) {
				throw new Error("No suitable storage found");
			}
			o = o || {};
			this.name = name;
			o.domain = o.domain || location.hostname || 'localhost';
			o.domain = o.domain.replace(/:\d+$/, '');
			o.domain = (o.domain == 'localhost') ? '' : o.domain;
			this.o = o;
			o.expires = o.expires || 365 * 2;
			o.path = o.path || '/';
			if (this.o.search_order) {
				C.search_order = this.o.search_order;
				init();
			}
			this.init();
		}
	};
	init();
	return P;
})();



转载于:https://my.oschina.net/u/246522/blog/326794

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值