肇庆网站搜索排名,网站怎么做自响应,东莞网页制作模版,深圳龙华天气HTML5本地存储Localstorage自从Html5中出现了本地存储的#xff08;LocalStorage)的概念后#xff0c;很多人都会想这个东西和我们传统web开发中的Cookie有什么特别之处#xff0c;当然笔者也是其中之一#xff0c;也难怪#xff0c;以前用惯了cookie对于新出现的事物总是…HTML5本地存储Localstorage自从Html5中出现了本地存储的LocalStorage)的概念后很多人都会想这个东西和我们传统web开发中的Cookie有什么特别之处当然笔者也是其中之一也难怪以前用惯了cookie对于新出现的事物总是会有些好奇那么相对于cookie,Html5中的究竟有什么优秀之处呢我们一起去看看吧① cookie大小限制在4k左右不适合存业务数据
② cookie每次随HTTP事务一起发送浪费带宽我们是做移动项目的所以这里真实适合使用的技术是localstoragelocalstorage可以说是对cookie的优化使用它可以方便在客户端存储数据并且不会随着HTTP传输但也不是没有问题① localstorage大小限制在500万字符左右各个浏览器不一致
② localstorage在隐私模式下不可读取
③ localstorage本质是在读写文件数据多的话会比较卡firefox会一次性将数据导入内存想想就觉得吓人啊
④ localstorage不能被爬虫爬取不要用它完全取代URL传参瑕不掩瑜以上问题皆可避免所以我们的关注点应该放在如何使用localstorage上并且是如何正确使用。localstorage的使用localstorage存储对象分为两种① sessionStrage session即会话的意思在这里的session是指用户浏览某个网站时从进入网站到关闭网站这个时间段session对象的有效期就只有这么长。② localStorage 将数据保存在客户端硬件设备上不管它是什么意思就是下次打开计算机时候数据还在。两者区别就是一个作为临时保存一个长期保存。这里来一段简单的代码说明其基本使用 1 div idmsg stylemargin: 10px 0; border: 1px solid black; padding: 10px; width: 300px;
2 height: 100px;
3 /div
4 input typetext idtext /
5 select idtype
6 option valuesessionsessionStorage/option
7 option valuelocallocalStorage/option
8 /select
9 button onclicksave();
10 保存数据/button
11 button onclickload();
12 读取数据/button
13 script typetext/javascript
14 var msg document.getElementById(msg),
15 text document.getElementById(text),
16 type document.getElementById(type);
17
18 function save() {
19 var str text.value;
20 var t type.value;
21 if (t session) {
22 sessionStorage.setItem(msg, str);
23 } else {
24 localStorage.setItem(msg, str);
25 }
26 }
27
28 function load() {
29 var t type.value;
30 if (t session) {
31 msg.innerHTML sessionStorage.getItem(msg);
32 } else {
33 msg.innerHTML localStorage.getItem(msg);
34 }
35 }
36 /script真实场景实际工作中对localstorage的使用一般有以下需求① 缓存一般信息如搜索页的出发城市达到城市非实时定位信息② 缓存城市列表数据这个数据往往比较大③ 每条缓存信息需要可追踪比如服务器通知城市数据更新这个时候在最近一次访问的时候要自动设置过期④ 每条信息具有过期日期状态在过期外时间需要由服务器拉取数据⑤ ...... 1 define([], function () {
2
3 var Storage _.inherit({
4 //默认属性
5 propertys: function () {
6
7 //代理对象默认为localstorage
8 this.sProxy window.localStorage;
9
10 //60 * 60 * 24 * 30 * 1000 ms 30天
11 this.defaultLifeTime 2592000000;
12
13 //本地缓存用以存放所有localstorage键值与过期日期的映射
14 this.keyCache SYSTEM_KEY_TIMEOUT_MAP;
15
16 //当缓存容量已满每次删除的缓存数
17 this.removeNum 5;
18
19 },
20
21 assert: function () {
22 if (this.sProxy null) {
23 throw not override sProxy property;
24 }
25 },
26
27 initialize: function (opts) {
28 this.propertys();
29 this.assert();
30 },
31
32 /*
33 新增localstorage
34 数据格式包括唯一键值json字符串过期日期存入日期
35 sign 为格式化后的请求参数用于同一请求不同参数时候返回新数据比如列表为北京的城市后切换为上海会判断tag不同而更新缓存数据tag相当于签名
36 每一键值只会缓存一条信息
37 */
38 set: function (key, value, timeout, sign) {
39 var _d new Date();
40 //存入日期
41 var indate _d.getTime();
42
43 //最终保存的数据
44 var entity null;
45
46 if (!timeout) {
47 _d.setTime(_d.getTime() this.defaultLifeTime);
48 timeout _d.getTime();
49 }
50
51 //
52 this.setKeyCache(key, timeout);
53 entity this.buildStorageObj(value, indate, timeout, sign);
54
55 try {
56 this.sProxy.setItem(key, JSON.stringify(entity));
57 return true;
58 } catch (e) {
59 //localstorage写满时,全清掉
60 if (e.name QuotaExceededError) {
61 // this.sProxy.clear();
62 //localstorage写满时选择离过期时间最近的数据删除这样也会有些影响但是感觉比全清除好些如果缓存过多此过程比较耗时100ms以内
63 if (!this.removeLastCache()) throw 本次数据存储量过大;
64 this.set(key, value, timeout, sign);
65 }
66 console console.log(e);
67 }
68 return false;
69 },
70
71 //删除过期缓存
72 removeOverdueCache: function () {
73 var tmpObj null, i, len;
74
75 var now new Date().getTime();
76 //取出键值对
77 var cacheStr this.sProxy.getItem(this.keyCache);
78 var cacheMap [];
79 var newMap [];
80 if (!cacheStr) {
81 return;
82 }
83
84 cacheMap JSON.parse(cacheStr);
85
86 for (i 0, len cacheMap.length; i len; i ) {
87 tmpObj cacheMap[i];
88 if (tmpObj.timeout now) {
89 this.sProxy.removeItem(tmpObj.key);
90 } else {
91 newMap.push(tmpObj);
92 }
93 }
94 this.sProxy.setItem(this.keyCache, JSON.stringify(newMap));
95
96 },
97
98 removeLastCache: function () {
99 var i, len;
100 var num this.removeNum || 5;
101
102 //取出键值对
103 var cacheStr this.sProxy.getItem(this.keyCache);
104 var cacheMap [];
105 var delMap [];
106
107 //说明本次存储过大
108 if (!cacheStr) return false;
109
110 cacheMap.sort(function (a, b) {
111 return a.timeout - b.timeout;
112 });
113
114 //删除了哪些数据
115 delMap cacheMap.splice(0, num);
116 for (i 0, len delMap.length; i len; i ) {
117 this.sProxy.removeItem(delMap[i].key);
118 }
119
120 this.sProxy.setItem(this.keyCache, JSON.stringify(cacheMap));
121 return true;
122 },
123
124 setKeyCache: function (key, timeout) {
125 if (!key || !timeout || timeout new Date().getTime()) return;
126 var i, len, tmpObj;
127
128 //获取当前已经缓存的键值字符串
129 var oldstr this.sProxy.getItem(this.keyCache);
130 var oldMap [];
131 //当前key是否已经存在
132 var flag false;
133 var obj {};
134 obj.key key;
135 obj.timeout timeout;
136
137 if (oldstr) {
138 oldMap JSON.parse(oldstr);
139 if (!_.isArray(oldMap)) oldMap [];
140 }
141
142 for (i 0, len oldMap.length; i len; i ) {
143 tmpObj oldMap[i];
144 if (tmpObj.key key) {
145 oldMap[i] obj;
146 flag true;
147 break;
148 }
149 }
150 if (!flag) oldMap.push(obj);
151 //最后将新数组放到缓存中
152 this.sProxy.setItem(this.keyCache, JSON.stringify(oldMap));
153
154 },
155
156 buildStorageObj: function (value, indate, timeout, sign) {
157 var obj {
158 value: value,
159 timeout: timeout,
160 sign: sign,
161 indate: indate
162 };
163 return obj;
164 },
165
166 get: function (key, sign) {
167 var result, now new Date().getTime();
168 try {
169 result this.sProxy.getItem(key);
170 if (!result) return null;
171 result JSON.parse(result);
172
173 //数据过期
174 if (result.timeout now) return null;
175
176 //需要验证签名
177 if (sign) {
178 if (sign result.sign)
179 return result.value;
180 return null;
181 } else {
182 return result.value;
183 }
184
185 } catch (e) {
186 console console.log(e);
187 }
188 return null;
189 },
190
191 //获取签名
192 getSign: function (key) {
193 var result, sign null;
194 try {
195 result this.sProxy.getItem(key);
196 if (result) {
197 result JSON.parse(result);
198 sign result result.sign
199 }
200 } catch (e) {
201 console console.log(e);
202 }
203 return sign;
204 },
205
206 remove: function (key) {
207 return this.sProxy.removeItem(key);
208 },
209
210 clear: function () {
211 this.sProxy.clear();
212 }
213 });
214
215 Storage.getInstance function () {
216 if (this.instance) {
217 return this.instance;
218 } else {
219 return this.instance new this();
220 }
221 };
222
223 return Storage;
224
225 });这段代码包含了localstorage的基本操作并且对以上问题做了处理而真实的使用还要再抽象 1 define([AbstractStorage], function (AbstractStorage) {
2
3 var Store _.inherit({
4 //默认属性
5 propertys: function () {
6
7 //每个对象一定要具有存储键并且不能重复
8 this.key null;
9
10 //默认一条数据的生命周期S为秒M为分D为天
11 this.lifeTime 30M;
12
13 //默认返回数据
14 // this.defaultData null;
15
16 //代理对象localstorage对象
17 this.sProxy new AbstractStorage();
18
19 },
20
21 setOption: function (options) {
22 _.extend(this, options);
23 },
24
25 assert: function () {
26 if (this.key null) {
27 throw not override key property;
28 }
29 if (this.sProxy null) {
30 throw not override sProxy property;
31 }
32 },
33
34 initialize: function (opts) {
35 this.propertys();
36 this.setOption(opts);
37 this.assert();
38 },
39
40 _getLifeTime: function () {
41 var timeout 0;
42 var str this.lifeTime;
43 var unit str.charAt(str.length - 1);
44 var num str.substring(0, str.length - 1);
45 var Map {
46 D: 86400,
47 H: 3600,
48 M: 60,
49 S: 1
50 };
51 if (typeof unit string) {
52 unit unit.toUpperCase();
53 }
54 timeout num;
55 if (unit) timeout Map[unit];
56
57 //单位为毫秒
58 return num * timeout * 1000 ;
59 },
60
61 //缓存数据
62 set: function (value, sign) {
63 //获取过期时间
64 var timeout new Date();
65 timeout.setTime(timeout.getTime() this._getLifeTime());
66 this.sProxy.set(this.key, value, timeout.getTime(), sign);
67 },
68
69 //设置单个属性
70 setAttr: function (name, value, sign) {
71 var key, obj;
72 if (_.isObject(name)) {
73 for (key in name) {
74 if (name.hasOwnProperty(key)) this.setAttr(k, name[k], value);
75 }
76 return;
77 }
78
79 if (!sign) sign this.getSign();
80
81 //获取当前对象
82 obj this.get(sign) || {};
83 if (!obj) return;
84 obj[name] value;
85 this.set(obj, sign);
86
87 },
88
89 getSign: function () {
90 return this.sProxy.getSign(this.key);
91 },
92
93 remove: function () {
94 this.sProxy.remove(this.key);
95 },
96
97 removeAttr: function (attrName) {
98 var obj this.get() || {};
99 if (obj[attrName]) {
100 delete obj[attrName];
101 }
102 this.set(obj);
103 },
104
105 get: function (sign) {
106 var result [], isEmpty true, a;
107 var obj this.sProxy.get(this.key, sign);
108 var type typeof obj;
109 var o { string: true, number: true, boolean: true };
110 if (o[type]) return obj;
111
112 if (_.isArray(obj)) {
113 for (var i 0, len obj.length; i len; i ) {
114 result[i] obj[i];
115 }
116 } else if (_.isObject(obj)) {
117 result obj;
118 }
119
120 for (a in result) {
121 isEmpty false;
122 break;
123 }
124 return !isEmpty ? result : null;
125 },
126
127 getAttr: function (attrName, tag) {
128 var obj this.get(tag);
129 var attrVal null;
130 if (obj) {
131 attrVal obj[attrName];
132 }
133 return attrVal;
134 }
135
136 });
137
138 Store.getInstance function () {
139 if (this.instance) {
140 return this.instance;
141 } else {
142 return this.instance new this();
143 }
144 };
145
146 return Store;
147 });我们真实使用的时候是使用store这个类操作localstorage代码结束简单测试存储完成以后都不会走请求于是今天的代码基本结束。其它隐私模式下可以采用window.name模拟sessionStorage的方式处理因为window.name是可做保存的这个也是其解决跨域方案的原因。在android Hybrid中有一后退按钮此按钮一旦按下会回到上一个页面这个时候里面的localstorage可能会读取失效一个简单不靠谱的解决方案是在webapp中加入window.onunload function () { };//适合单页应用不要问我为什么我也不知道