相比于桌面应用,Web应用在本地存储方面确实显得有点力不从心。在桌面应用,你可以使用INI或者XML等文件来保存配置和数据,甚至可以使用内嵌小型数据库的方法去保存数据,而对于网站来说,在很长的一段时间里,我们只能使用Cookies这个充满缺点但又无法替代的东西。不过随着互联网的发展,本地存储技术也一直在发展,但始终没有出现一个能满足需求的技术,直到Web Storage的出现。
下面我们来看下一些比较常见的本地存储技术。 Cookies
这个由Netscape的前雇员Lou Montulli在1993年3月的发明的东西,至今仍然被广泛的应用在各网站上,我们用它来保存登录状态,用它来保存浏览过的商品,用它来保存购物车物品,等等。
目前cookie存在了以下几种的规范:
想深入了解Cookie可以研究下这些规范,但这篇文章里并不会再深入进去,这里列出几个规范除了扫盲外主要是为了解释一个问题,什么是cookie?Netscape的cookie草案里是这么说的:
下面我们来看看浏览器,web服务器跟cookie之间的交互是怎样的:
至于哪些cookie会被发送到服务器端,是有一套规则的,例如域名选择、路径选择和Max-Age选择,这些都可以在RFC2109里找到,这里就不展开了。
从上面可以看到,每次的http请求,cookie都会包含在包头里发送给服务器,这也是被开发者广为诟病的一个cookie缺点,因为这意味这每个请求都无形中增加了流量,特别是像请求图片这些资源的时候,附带的cookie信息是完全没有必要的。所以现在很多网站图片等静态资源都会用独立的域名运作,这样就可以单独对这些域名进行cookie设置。 除此以外,cookie还有以下影响比较大的缺点:
关于Cookies的一些限制问题,可以参考下Nicholas的一篇文章: 浏览器允许的每个域名下的Cookie数:
那如果Cookie数设置超过限制的时候,各浏览器又是如何处理呢:
cookie的总大小在各浏览器中也是不同的:
注意这里用的字节,也就是,如果是多字节字符,自然就会占用两个字节。在所有浏览器里,如果设置的cookie大小超过限制,那么它就会被忽略或者不被设置。
从上面,我们可以看到,Cookie确实存在一些不足,但是它的一些缺点也正是它的优点,例如每个请求都会被放到包头里发送给服务器,正是这个特性我们才能很方便的传输sessionid。Cookie的出现可谓大大推动了网页的发展,而且在未来很长的一段时间里,Cookie还会继续发挥它的作用。但是也正是由于Cookie存在种种的不足,才会有新的本地存储技术出现的需求。
userData是微软在第一次浏览器大战中的产物,属于DHTML中的一种技术。相比起Cookie,userData在每个域名下可存储达的数据提升了不少,但是具体的大小视domain的安全域而定:
SECURITY ZONEDOCUMENT LIMIT (KB)DOMAIN LIMIT (KB)
Local Machine 128 1024
Intranet 512 10240
Trusted Sites 128 1024
Internet 128 1024
Restricted 64 640
总的来说,考虑到各种情况,最安全的做法是把文件控制在64K以下。文件的数据是XML格式,保存在系统盘的某个目录下,例如在XP下(假设C为系统盘),保存的位置为C:\Documents and Settings\用户名\UserData或C:\Documents and Settings\用户名\Application Data\Microsoft\Internet Explorer\UserData下,而在VISTA下则保存在C:\Users\用户名\AppData\Roaming\Microsoft\Internet Explorer\UserData下。 userData支持IE5以上的浏览器,要使用userData,必须以一个HTML元素作为宿主。也就是说,userData并不能单独使用,而必须依附于某个HTML标签上,并设置behavior:
XML <Prefix: CustomTag ID=sID" target="_blank">behavior:url('#default#userData')" />
HTML <ELEMENT ID=sID>
SCRIPTING object.style.behavior = "url('#default#userData')"
object.addBehavior("#default#userData")
但需要注意的是并不是所有的HTML标签都能用于userData,例如绑定userData到html、head、title或者style上进行存储时就会发生错误。
userData的数据会一直存在,直到被删除或者到过期时间。并且基于安全的考虑,一个 userData 存储区只能用于同一目录和对同一协议进行存储。
跟cookie一样,userData的数据也是没有进行加密的,所以也不建议把一些重要信息保存在里面。
userData在数据的本地储存来说,比cookie进步了不少,但是它有个致命的缺点:仅支持IE。仅凭这一点,就注定了userData并不会有太大的作为,只能用作配合其他本地存储技术兼容低版本的IE。
userData具体的使用方法这里就不深入了,详情可以参阅微软的文档。
2002年,Adobe在Flash6中引入了一个新功能,并很不幸的获取了一个及具有迷惑性的名字:“Flash Cookies”。 但在Flash中,这个功能被称作Local Shared Objects或者LSO更为合适。 简单来说,这个技术允许Flash对象在每个域名上存储100KB的数据。
2005年,Brad Neuberg开发了一个早期的Flash到JavaScript的桥接原型接口,叫AJAX Massive Storage System(AMASS),但是受到Flash技术的种种局限。
2006年,随着Flash 8的ExternalInterface的引入,在Javascript中访问LSO变得更加简单和快速。Brad重写了AMASS并把它整合到流行的Dojo工具框架中,取名dojox.storage。同时这个技术也允许每个域名下存储100K的数据,而超过这个限制则要增加到下一个大小等级(1MB,10MB等),就会弹出提示让用户确认。
Adobe Flash Player不允许第三方的LSO进行跨域分享。例如,一个的LSO不能被读取。然而第一方的网站可以通过专门的XML文件上的设置传送数据给第三方。
用户可以通过在Adobe网站上的全局存储设置面板禁用LSO,也可以右击Flash Player,在设置里对每个网站的设置进行调整。后面的方法也允许用户删除LSO。当然用户也可以手动或者借助第三方的软件来删除LSO。
直到版本10.1,Adobe Flash Player才支持浏览器的私隐模式,支持的浏览器包括Chrome,Firefox,IE和Safari。
LSO解决了上面提到的Cookie的一些问题,例如大小,安全等。跟Cookie不同,LSO被保存为二进制文件(不过变量名具有可读性)。作为本地存储的替代方案,LSO具有了不少优点,但是缺点也是明显,就是它需要安装Flash这个插件。虽然现在Flash的普及率很高,但是这种依赖插件的技术始终不能解决问题的根源,而且为了使用这个方案,我们不得不引入额外的swf和js文件。
P.S. 本人极不喜欢Flash……