目前流行前后端分离,通常H5浏览器没多大问题,如果在IE8等低版本浏览器中,会导致N中问题出现,这篇日志主要提供前后端分离后的本地存储兼容问题解决方案。

本地存储数据的问题。如果ie不是国内最广泛的浏览器,如果ie9(ie8存在一些问题,后面再说)已经得到普及,那么一切就都很简单了,用html5的localstorage,一切都变得异常简单——谷歌浏览器早就支持localstorage了,但ie支持得很晚。

应用场景

userData是微软为IE专门在系统中开辟的一块存储空间,所以说只支持Windows+IE的组合,实际测试在2000(IE5.5)、XP(IE6、IE7),Vista(IE7)下都是可以正常使用的。

Internet Explorer不同安全区域中的userData存储能力

安 全 区 域 页大小限制 域大小限制
Intranet 512KB 10MB
本机、可信任区域及Internet 128KB 1MB
受限制区域 64KB 640KB

线上使用时,单个文件的大小限制是128KB,一个域名下总共可以保存1024KB的文件,文件个数应该没有限制。在受限站点里这两个值分别是64KB和640KB,所以如果考虑到各种情况的话,单个文件最好能控制64KB以下。

使用示例

用下面的JS语句就可以建立一个支持userData的对象:

1
2
3
4
5
6
var elm = document.createElement('input');
elm.type = "hidden";
elm.addBehavior ("#default#userData");
//userData.o.style.behavior = "url('#default#userData')" ;
//上面的语句也是一样的作用
document.body.appendChild(elm);

说白了userData就是样式里的一个Behavior(特性),所以这样写也是一样的:

1
2
3
4
<input type="hidden" class="storeuserData" />
<style>
.storeuserData {behavior:url(#default#userData);}
</style>

userData可以绑定在大多数的html标签上,具体为:

1
2
3
4
5
6
7
8
A, ACRONYM, ADDRESS, AREA, B, BIG, BLOCKQUOTE,
BUTTON, CAPTION, CENTER, CITE, CODE, DD, DEL,
DFN, DIR, DIV, DL, DT, EM, FONT, FORM,
hn, HR, I, IMG, INPUT,
KBD, LABEL, LI, LISTING, MAP, MARQUEE,
MENU, OBJECT, OL, OPTION, P, PLAINTEXT, PRE,
Q, S, SAMP, SELECT, SMALL, SPAN, STRIKE, STRONG,
SUB, SUP, TABLE, TEXTAREA, TT, U, UL, VAR, XM

userData属性说明

属性 描述
expires 设置或读取文件过期时间
XMLDocument 读取文件的XML DOM
方法 描述
getAttribute 读取指定属性的值
load 打开文件
removeAttribute 删除指定的属性
save 保存文件
setAttribute 为指定属性赋值

userData文件实际上就是一个XML文件,通过文件名->属性的方式保存字符串,如以下一段代码:

1
2
elm.setAttribute("code", "hello world!");
elm.save("baidu");

执行后,userData文件夹中会生成一个baidu[1].xml文件,其中的内容是:

1
<ROOTSTUB code="hello,world!"/>

在一个文件中可以有多个属性,也就是可以存储多种不同的数据。

封装userData类

封装了一个userData类,这样可以更方便地使用userData,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
/** @class 定义userData的操作 */
var userData = {
// 定义userData对象
o : null,
// 设置文件过期时间
defExps : 365,
// 初始化userdate对象
init : function(){
if(!userData.o){
try{
userData.o = document.createElement('input');
userData.o.type = "hidden";
//userData.o.style.behavior = "url('#default#userData')" ;
userData.o.addBehavior ("#default#userData");
document.body.appendChild(userData.o);
}catch(e){
return false;
}
};
return true;
},
// 保存文件到userData文件夹中 f-文件名,c-文件内容,e-过期时间
save : function(f, c, e){
if(userData.init()){
var o = userData.o;
// 保持对象的一致
o.load(f);
// 将传入的内容当作属性存储
if(c) o.setAttribute("code", c);
// 设置文件过期时间
var d = new Date(), e = (arguments.length == 3) ? e : userData.defExps;
d.setDate(d.getDate()+e);
o.expires = d.toUTCString();
// 存储为制定的文件名
o.save(f);
}
},
// 从uerdata文件夹中读取指定文件,并以字符串形式返回。f-文件名
load : function(f){
if(userData.init()){
var o = userData.o;
// 读取文件
o.load(f);
// 返回文件内容
return o.getAttribute("code");
}
},
// 检查userData文件是否存在 f-文件名
exist : function(f){
return userData.load(f) != null;
},
// 删除userData文件夹中的指定文件 f-文件名
remove : function(f){
userData.save(f, false, -userData.defExps);
}
// userData函数定义结束
};