IE下Userdata本地化存储
这两天看了下Discuz x2发帖的实时保存机制,涉及到本地化存储,所以上网查了下,Firefox等支持HTML5的浏览器使用window.localStorage或window.sessionStorage存储,比较简单,所以我特别关注了一下IE下的本地化存储,以下是在网上查找的资料,作为笔记。
在Internet Explorer 5中,Microsoft提供了名为userData的客户端持久存储功能。它是通过对CSS行为进行特殊扩展来实现的。这些扩展完全都是非标准的,是 90年代后期浏览器大战遗留下来的产物。由于它概念模糊、使用困难,并且只能用于Internet Explorer,所以很少有Web开发人员会使用这种存储方式,大多数的开发人员甚至完全不知道存在这种技术。
IE的userData能 够存储完整的XML文档,并且会将复杂的数据类型转换为XML存储起来。通过这种方 式,数据会被插入到XML数据岛(另一项只有IE中才存在的功能)中。然后整个XML数据岛再被存入userData中。不过,像 Dojo.Storage这样的存储框架屏蔽了userData中的这些XML功能,通常只将名/值对以字符串的形式暴露出去。
在某些情况 下,userData可以比其他存储方式存储更多的数据。Internet Explorer中不仅对每页数据的大小作出了限制,同时也对整个域的大小进行了限制。如果试图存储的数据容量超过了允许的大小,就会导致 JavaScript抛出一个异常。表8-2显示了Internet Explorer不同安全域中userData的存储能力。
表 Internet Explorer不同安全区域中的userData存储能力
| 安 全 区 域 | 域大小限制 | 页大小限制 |
| Intranet | 512KB | 10MB |
| 本机、可信任区域及Internet | 128KB | 1MB |
| 受限制区域 | 64KB | 640KB |
表中两个关系最紧密的域就是Internet和 Intranet。对于互联网上的普通网站来说,IE本身允许的存储容量要大于Flash的LSO,但是小于Mozilla的DOM存储。而对于 Intranet中的应用程序来说,userData的存储能力远远超过其他存储方式,10MB的存储容量可以存储下整个数据表、树型结构及其他体积更大 的数据结构。开发人员必须记住,userData是一种持久化存储方式,而不是驻留在内存中,因此关闭浏览器并不会删除这些数据。当使用userData 存储体积较大的数据结构时,开发人员需要格外小心。因为这些数据结构中可能会存有身份认证这样的敏感数据,如果被持久保存在客户端很可能被攻击者所利用。
由于名/值对是作为XML节点的属性存储在userData的XML文档中,因此Internet Explorer可以自动将某些特殊字符转义为XML中的对应字符。例如,双引号(”)会被替换为",而连字符(&)会被替换 为&。由于这些自动转义的字符会增加实际存储的数据大小,因此开发人员必须确保有足够的空间来存储转义后的数据。
使用 userData将会使数据共享受到极大的限制。不同域、甚至同一域下的不同子域之间都不能共享数据。此 外,同一主机不同端口上的应用程序之间也无法共享数据。我们只能在同域同目录下的不同页面之间共享数据。例如,http://company.com /Storage/ Checkout.html可以访问http://company.com/Storage/ UserData.html,以及任何/Storage/目录下网页所存储的数据。如果试图从其他页面访问,仅会返回一个null。这些默认的限制是无法 改变的,并且几乎与cookie的默认规则恰恰相反。这也使得userData成为了Internet Explore 5中少数几个较为安全的功能之一。
我们无法通过编程手段来删除掉存储在userData中的所有数据,只能对使用.userData样式的 HTML元素调用其removeAttribute()方法,来删除相应的名/值对。但是,我们无法遍历删除userData中实际存储的名/值对。虽然 开发人员应该知道存储在客户端的所有名/值对,但是,我们毕竟都是人,总会忘记一些事情,并且由于我们无法像为DOM存储编写一个clear()方法那 样,所以那些应该被删除的数据很可能被遗留在userData中。幸好,userData元素的expires属性可以提供一些帮助,开发人员可以通过它 来设置自动删除数据的过期时间。在默认情况下,存储在userData中的所有数据永远都不会过期。Interner Explorer不仅无法提供网站使用userData存储数据的时间,也没有提供任何关于userData的可视化界面,即使删除浏览器中的 cookie、缓存、历史记录和离线内容,也无法删除userDat中存储的数据。这些因素都增加了窃取客户端机器中数据的可能性。一旦确保不再需要使用 应用程序中的某些数据,开发人员就应该立即将它们删除掉。
要查看userData中存储的数据不是不可行,但需要一些技巧。首先,在 Windows Explorer(随便打开一个Windows文件窗口)的文件夹选项中切换到“查看”选项卡,勾选“显示所有文件和文件夹”复选框,并取消选择“隐藏受 保护的操作系统文件(推荐)”选项。然后我们打开userData目录,在Windows XP系统中即为C:\Documents and Settings\USER_NAME\UserData。虽然userData都存储在XML文件中,但是Internet Exploerer使用缓存的存储机制来存储这些XML。例如,用一个名为index.dat的索引文件来存储所有的元数据(Metadata),然后将 其中的元素(即不同域用来存储userData的XML)分别存储在5个随机生成的目录下。我们可以通过查看index.dat索引文件,以及目录中的所 有XML文件,来确定具体使用的userData存储系统。
不过,要想修改userData中存储的内容却是非常复杂的,因为我们无法直 接修改缓存目录中的XML文件。 如果真这么做,那么JavaScript在加载修改后的数据时,会抛出一个数据格式错误的异常。这意味着在index.dat文件中保存了某些哈希散列 值,或者XML文件的长度。不幸的是,index.dat不是一种开放的文件格式。在互联网上,只有很少一些网站详细描述了该文件结构的内部结构。我们 (本书作者)经过一晚上大量的尝试和失败,终于发现XML文件的长度的确存储在index.dat文件中。注意,index.dat里 的+0x20偏移量就用来保存文件的长度,当前值为136字节,也正是我们用来存储持久化userData的XML文件的长度。
于是,现在攻击者可以任意修改userData中存储的持久化数据,只要最后更新index.dat文件中的 XML文件长度即可。
我们再一次重申,任何形式的客户端存储都可以被用户查看并修改。开发人员永远都不能相信任何来自客户端的数据。
总结
· userData提供了持久化存储功能。如果要模拟非持久化存储,开发人员可以使用浏览器的unload()方法来清除userData数据。
· 可以指定userData是否自动过期。在默认情况下,userData中的数据永远不会过期。
· 只有满足以下3个条件,页面之间才能共享userData数据:同一端口、同一服务器、同一目录下。必须遵守该规定,并且域和域之间也无法共享数据。
· userData可以存储XML或者字符串数据。开发人员必须将复杂的数据类型进行序列化,转化为这两种格式,并实现相应的反序列化功能。
· 通过文本编辑器就可以查看userData中的数据,而修改其中的数据需要十六进制编辑器。
程序代码封装:
/** @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){
try{
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);
}
}catch (ex){}
},
// 从uerdata文件夹中读取指定文件,并以字符串形式返回。f-文件名
load : function(f){
if(UserData.init()){
try{
var o = UserData.o;
// 读取文件
o.load(f);
// 返回文件内容
return o.getAttribute("code");
}catch (ex){
return null;
}
}
},
// 检查userdata文件是否存在 f-文件名
exist : function(f){
return UserData.load(f) != null;
},
// 删除userdata文件夹中的指定文件 f-文件名
remove : function(f){
UserData.save(f, false, -UserData.defExps);
}
// UserData函数定义结束
}; //调用方式 UserData.save(fileName,"存储内容"); var "存储内容"=UserData.load(fileName);
IE下Userdata本地化存储的更多相关文章
- 从javascript读取cookies说开去:谈谈网页的本地化存储
学习要点:1.cookies 2.cookies 局限性 3.其他存储 随着 Web 越来越复杂,开发者急切的需要能够本地化存储的脚本功能.这个时候,第一个出现的方案:cookie 诞生了.cooki ...
- LINUX系统下添加映射存储LUN
LINUX系统下添加映射存储LUN(无需重启) 背景:Oracle rac环境 添加新实例,重新划分存储空间,从存储映射新的LUN. 问题:映射后,linux操作系统无法识别新的LUN,不能重启系统, ...
- 分布式集群下的Session存储方式窥探
传统的应用服务器,自身实现的session管理是大多是基于单机的,对于大型分布式网站来说,支撑其业务的远远不止一台服务器,而是一个分布式集群,请求在不同的服务器之间跳转.那么,如何保持服务器之前的se ...
- Android下的数据存储与訪问 --- 以文件的形式
Android下的数据存储与訪问 --- 以文件的形式 1.1 储存文件存放在手机内存中: // *** 储存数据到 /data/data/包名/files/jxn.txt文件里 String dat ...
- devicemapper存储驱动下镜像的存储
docker配置devicemapper存储驱动 #查看当前使用的存储驱动,默认为overlay docker info | grep -i storage #停止dockersystemctl st ...
- ie6 ie7 userdata 本地存储 引发的惨案.
我使用 documentElement 作为userdata 作为本地存储的载体. document.documentElement.addBehavior("#default#userda ...
- Asp.Net在多线程环境下的状态存储问题
在应用开发中,我们经常需要设置一些上下文(Context)信息,这些上下文信息一般基于当前的会话(Session),比如当前登录用户的个人信息:或者基于当前方法调用栈,比如在同一个调用中涉及的多个层次 ...
- 论文学习 - 《Hadoop平台下的海量数据存储技术研究》
摘要 研究背景: 1. 互联网的图片数据急剧膨胀 2. Hadoop平台下的Hdfs分布式文件系统能够很好的处理海量数据 研究内容: 1. Hadoop平台工作原理 2. Hadoop平台下图片存储系 ...
- android下的数据存储
android下数据存储的几种方式:(简单讨论) 1.文件 举例:登陆时“记住密码” 因为是基于Linux系统,直接建文件,文件会出现在项目工程:而手机登陆时,应该把文件放在手机里,通常数据放在dat ...
随机推荐
- STM8S——watchdog(IWDG)
IWDG工作原理: 1.当键值寄存器(IWDG_KR)中写入数值0xCC后,独立看门狗就会被启动,计数器开始从它的复位值0xFF开始递减计数,当计数减到0x00时就会产生一个复位信号. 2.使用IWD ...
- STM平台增加性能测试/稳定性测试部分【一】
前置 我之前写了一个接口自动化平台的,后期因为一个原因删除了. 现在,在此平台的基础上,我又增加了性能/稳定性的功能 它的前端大概是这样: 数据解析: 图表展示: 我将稳定性及性能归与一套方案去编写, ...
- Linux命令应用大词典-第1章 登录、退出、关机和重启
1.1 login:用户登录系统 1.2 logout:退出登录shell 1.3 nologin:限制用户登录 1.4 exit:退出shell 1.5 sulogin:单用户登录(single u ...
- 在WebGL场景中进行棋盘操作的实验
这篇文章讨论如何在基于Babylon.js的WebGL场景中,建立棋盘状的地块和多个可选择的棋子对象,在点选棋子时显示棋子的移动范围,并且在点击移动范围内的空白地块时向目标地块移动棋子.在这一过程中要 ...
- TPO-21 C2 Which elective courses to take
/* 加粗:语音部分 * 红色:单词部分 * 斜体:语法部分 * 下划线:信号词/句 */ 第 1 段 1.Listen to a conversation between a student and ...
- [工具]chrome添加crx扩展程序(附禁止复制破解扩展)
Hello亲爱的观众朋友们大家好,我是09. 今天带来墙内用户安装chrome插件的方法. 1.打开扩展程序 2.把crx往里拖,欧了. ps.顺带安利chrome禁止复制破解扩展Enable Cop ...
- 006 --MySQL索引原理
一 .索引的概念? 一般的应用系统,读写比例在10:1左右,而且插入操作和一般的更新操作很少出现性能问题,在生产环境中,我们遇到最多的,也是最容易出问题的,还是一些复杂的查询操作,因此对查询语句的优化 ...
- jQuery的基本使用
一.jQuery简介 jQuery是一个快速.简洁的JavaScript框架,它封装了JavaScript常用的功能代码,提供一种简便的JavaScript设计模式,优化HTML文档操作.事件处理.动 ...
- 关于Python的面试题
Python语言特性 1 Python的函数参数传递 看两个例子: a = 1 def fun(a): a = 2 fun(a) print a # 1 a = [] def fun(a): a.ap ...
- Arithmatic项目修改总结
Arithmatic项目修改总结 github仓库 arithmatic3.0 一. 修改介绍 修改后类图: 1.关于类的合并 ==可以发现相比右边(旧)的类,左边(新)的类少了很多,这是我这次大改的 ...