当我们在提及web前端本地存储的时候,首先需要介绍一下本地化存储的概念和历史。本地化存储从来不是一个新奇的概念,因为web应用程序一直在追求的就是媲美甚至超越桌面应用程序。但是桌面应用程序一直优于web应用程序一个很重要的原因是它的本地化存储得到了很好的支持。对于本地应用程序,操作系统会提供一个抽象层,用于存储和获取特定于应用程序的数据,这些数据可以存储于注册表、INI文件,或者其他什么地方,这取决于操作系统的实现,如果本地应用程序需要不单是键值对形式的本地存储,可以使用嵌入式数据库或其他很多种解决方案。而对于web应用程序,它的本地存储一步一步走到今天的HTML5本地存储是非常不容易的。为了描述它的历史,我们可以先看一张图片:

  从图片可以看出,无论是从存储数据的大小还是兼容性来看,web前端本地存储都走得不容易。在着重介绍HTML5本地存储之前,我们先来看一看前面几个存储方式的概念。

  HTTP cookie:HTTP cookie的缺点很明显,最多只能存储4KB的数据,每个HTTP请求都会被传送回服务器,明文传输(除非你使用SSL)。

  IE userData:userData是微软在上世纪90年代的浏览器大战时推出的本地存储方案,借助DHTML的behaviour属性来存储本地数据, 允许每个页面最多存储64K数据,每个站点最多640K数据,userData的缺点显而易见,它不是Web标准的一部分,除非你的程序只需要支持IE, 否则它基本没什么用处。

  Flash cookie:Flash cookie的名字有些误导,它实际上和HTTP cookie并不是一回事,或许它的名字应该叫做"Flash本地存储”,Flash cookie默认允许每个站点存储不超过100K的数据,如果超出了,Flash会自动向用户请求更大的存储空间,借助Flash的 ExternalInterface接口,你可以很轻松地通过Javascript操作Flash的本地存储。Flash的问题很简单,就是因为它是 Flash。

  Google Gears:Gears是Google在07年发布的一个开源浏览器插件,旨在改进各大浏览器的兼容性,Gears内置了一个基于SQLite的嵌入式 SQL数据库,并提供了统一API对数据库进行访问,在取得用户授权之后,每个站点可以在SQL数据库中存储不限大小的数据,Gears的问题就是 Google自己都已经不用它了。

  从上面的简介我们可以看出,在以前,本地存储面临的主要问题是,对于存储容量较大的方式,需要特定的插件支持;对于不需要插件支持的存储方式,则处于安全问题或者大小限制而遭到扼杀。在这种双重的矛盾面前,HTML5本地存储横空出世,对于前端开发人员是一种巨大的福音。

  所谓的HTML5本地存储更精确的说法应该是DOM存储。根据MDN的定义,DOM存储的机制是通过存储字符串类型的键/值对,来提供一种安全的存取方式.这个附加功能的目标是提供一个全面的,可以用来创建交互式应用程序的方法(包括那些高级功能,例如可以离线工作一段时间)。

  HTML5的DOM存储分成两种:SessionStorage和LocalStorage。在当代浏览器中的兼容性如下:

  上图中提及的globalStorage是非标准的,已经废弃,在这里我们直接忽略它。而sessionStorage和localStorage在绝大部分现代浏览器中已经得到了很好的支持,但是既然是绝大部分,就必须照顾那些还不支持这两个对象的浏览器。为了检测浏览器是否支持这两个对象,我们可以简单的用下面的代码来检测:

 function storageSupport() {
try {
return 'localStorage' in window && window['localStorage'] !== null;
} catch (e) {
return false;
}
}

  非常幸运的是,这两种对象的使用方式都非常简单,这里借用网上 的一张图:

     

  首先我们来看一看sessionStorage,sessionStorage 是个全局对象,它维护着在页面会话(page session)期间有效的存储空间。只要浏览器开着,页面会话周期就会一直持续。当页面重新载入(reload)或者被恢复(restores)时,页面会话也是一直存在的。每在新标签或者新窗口中打开一个新页面,都会初始化一个新的会话。这句话看起来比较抽象,我们直接看一个demo:

 var name = sessionStorage.setItem("myname","yuanzm");
alert(sessionStorage.getItem("myname"));

  当我们在浏览器中打开的时候,就会弹出窗口,显示“yuanzm”,然后我们按F12键,查看浏览器的调试窗口:

  

  我们能够发现,在浏览器的本地存储sessionStorage中已经有了key值为“myname”的项。这个时候,刷新页面,仍然会弹出“yuanzm”,因为如果不调用sessionStorage.removeItem()或者手动清除这个项的话,这个项将一直存在。而上面提到的“只要浏览器开着,页面会话周期就会一直持续。当页面重新载入(reload)或者被恢复(restores)时,页面会话也是一直存在的。每在新标签或者新窗口中打开一个新页面,都会初始化一个新的会话”的意思是说,如果我们不重新设置myname的值,在新打开一个浏览器标签或者再次打开一个浏览器窗口的时候,这个值是不存在的,也就是null。为了验证这一点,很简单,我们把上面两行代码的第一行注释掉,然后刷新页面,接着在新的浏览器标签中打开这个文件。这两个动作分别会产生什么效果呢?答案很简单,当再次刷新页面的时候,仍然会弹出“yuanzm”,因为这个数据已经保存在本地了,而修改代码之后在新的页面打开,得到的结果是null,因为当前页面会话中没有“myname”这个值。

  接下来我们看一看localStorage,他是跨多个窗口,且持续范围可超过当前会话;意味着当浏览器关闭再重新打开,数据依然是可用的;拿上面的例子来说,当修改代码之后,在新的标签打开页面,仍然会弹出“yuanzm”,我们再次在浏览器中查看效果:

  

  由于这两个对象的使用很简单,暂时就介绍到这里。下面还需要介绍一下的就是兼容性问题。原因很简单,因为并不是所有的浏览器都支持这两个对象。这里的兼容包括两种,第一种是在没有原生支持localStorage的浏览器中使用,第二种是兼容不同浏览器对于这两种用法的差异。对于第一种,MDN给出了兼容代码:

if (!window.localStorage) {
Object.defineProperty(window, "localStorage", new (function () {
var aKeys = [], oStorage = {};
Object.defineProperty(oStorage, "getItem", {
value: function (sKey) { return sKey ? this[sKey] : null; },
writable: false,
configurable: false,
enumerable: false
});
Object.defineProperty(oStorage, "key", {
value: function (nKeyId) { return aKeys[nKeyId]; },
writable: false,
configurable: false,
enumerable: false
});
Object.defineProperty(oStorage, "setItem", {
value: function (sKey, sValue) {
if(!sKey) { return; }
document.cookie = escape(sKey) + "=" + escape(sValue) + "; path=/";
},
writable: false,
configurable: false,
enumerable: false
});
Object.defineProperty(oStorage, "length", {
get: function () { return aKeys.length; },
configurable: false,
enumerable: false
});
Object.defineProperty(oStorage, "removeItem", {
value: function (sKey) {
if(!sKey) { return; }
var sExpDate = new Date();
sExpDate.setDate(sExpDate.getDate() - 1);
document.cookie = escape(sKey) + "=; expires=" + sExpDate.toGMTString() + "; path=/";
},
writable: false,
configurable: false,
enumerable: false
});
this.get = function () {
var iThisIndx;
for (var sKey in oStorage) {
iThisIndx = aKeys.indexOf(sKey);
if (iThisIndx === -1) { oStorage.setItem(sKey, oStorage[sKey]); }
else { aKeys.splice(iThisIndx, 1); }
delete oStorage[sKey];
}
for (aKeys; aKeys.length > 0; aKeys.splice(0, 1)) { oStorage.removeItem(aKeys[0]); }
for (var iCouple, iKey, iCouplId = 0, aCouples = document.cookie.split(/\s*;\s*/); iCouplId < aCouples.length; iCouplId++) {
iCouple = aCouples[iCouplId].split(/\s*=\s*/);
if (iCouple.length > 1) {
oStorage[iKey = unescape(iCouple[0])] = unescape(iCouple[1]);
aKeys.push(iKey);
}
}
return oStorage;
};
this.configurable = false;
this.enumerable = true;
})());
}

  至于第二种,在github上面有很多优秀的代码,博主这里推荐其中一份:github localStorage

   最后,欢迎转载原文,但是希望加上转载链接:http://www.cnblogs.com/yuanzm/p/4023295.html

web前端实现本地存储的更多相关文章

  1. 前端之本地存储和jqueryUI

    本地存储 本地存储分为cookie,以及新增的localStorage和sessionStorage 1.cookie 存储在本地,容量最大4k,在同源的http请求时携带传递,损耗带宽,可设置访问路 ...

  2. 前端开发本地存储之localStorage和sessionStorage

    1.localStorage 概念 HTML5 web 存储:HTML5 提供了两种在客户端存储数据的新方式:localStorage 和 sessionStorage ,两者都是仅在客户端(即浏览器 ...

  3. 前端开发本地存储之cookie

    1.cookie cookie是纯文本,没有可执行代码,是指某些网站为了辨别用户身份.进行 session 跟踪而储存在用户本地终端(浏览器)上的数据(通常经过加密).当用户访问了某个网站的时候,我们 ...

  4. Html5 学习系列(六)Html5本地存储和本地数据库

    一个网站如何能在客户的浏览器存储更多的数据呢? 在Html4的时代在浏览器端存储点网站个性化的数据,尤其是用户浏览器的痕迹,用户的相关数据等一般只能存储在Cookie中,但是大多是浏览器对于Cooki ...

  5. (转)HTML5开发学习(2):本地存储之localStorage 、sessionStorage、globalStorage

    原文:http://www.cnblogs.com/xumingxiang/archive/2012/03/25/2416386.html HTML5开发学习(2):本地存储之localStorage ...

  6. Html5本地存储和本地数据库

    一个网站如何能在客户的浏览器存储更多的数据呢? 在Html4的时代在浏览器端存储点网站个性化的数据,尤其是用户浏览器的痕迹,用户的相关数据等一般只能存储在Cookie中,但是大多是浏览器对于Cooki ...

  7. HTML5本地存储和本地的数据库

    一个网站如何能在客户的浏览器存储更多的数据呢? 在Html4的时代在浏览器端存储点网站个性化的数据,尤其是用户浏览器的痕迹,用户的相关数据等一般只能存储在Cookie中,但是大多是浏览器对于Cooki ...

  8. H5本地存储(转)

    H5本地存储  一.本地存储由来的背景         众所周知Html4时代Cookie的大小.格式.存储数据格式等限制,网站应用如果想在浏览器端存储用户的部分信息,那么只能借助于Cookie.但是 ...

  9. [web 前端] web本地存储(localStorage、sessionStorage)

    cp from : https://blog.csdn.net/mjzhang1993/article/details/70820868 web 本地存储 (localStorage.sessionS ...

随机推荐

  1. C# 基于MySQL的数据层基类(MySQLHelper)

    这里介绍下比较简单的方式,引用MySql.Data.dll然后添加一个MySqlHelper类来对MySql数据库进行访问和操作. 1.将MySql.Data.dll引用到你的项目中 下载地址:MyS ...

  2. Mask-RCNN数据集制作

    转自https://blog.csdn.net/pingushen2100/article/details/80513043 一.Mask-RCNN数据集 1.1 训练Mask-RCNN用的到的文件有 ...

  3. sql数据库连接字符串在APP.config配置文件内的两种写法

    第一种方法 写法: <configuration> <appSettings> <add key="connectionstring" value=& ...

  4. html5 canvas多个图像旋转

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  5. 【转】UICollectionView使用介绍

    CHENYILONG Blog UICollectionView 使用介绍 技术博客http://www.cnblogs.com/ChenYilong/ 新浪微博http://weibo.com/lu ...

  6. HDU 4472 Count DP题

    解题报告:题目大意,给你n个球,要将这n个球从下到上按层次排列,要求同一个层次的的每一个分支的数量都必须相等,问有多少种排列的方法. 此题的一个DP题,假设现在有n个球,要将这n个球排列好,我们就必须 ...

  7. Servlet笔记7--HttpServletRequest介绍

    通过HttpServletRequest获取表单提交的数据: 前端页面: <html> <head> <title>register</title> & ...

  8. vim助手

    移动光标 hjkl 2w 向前移动两个单词 3e 向前移动到第 3 个单词的末尾 0 移动到行首 $ 当前行的末尾 gg 文件第一行 G 文件最后一行 行号+G 指定行 <ctrl>+o ...

  9. SQL Server修改默认端口号1433

    方法1: 1) SqlServer服务使用两个端口:TCP-1433.UDP-1434. 其中1433用于供SqlServer对外提供服务,1434用于向请求者返回SqlServer使用了那个TCP/ ...

  10. css初始化minireset.css

    一个很小的现代CSS重置,涵盖了基本内容: 重置字体大小:这样使用语义标记不会影响样式 重置块边距:所以只有在需要时才应用间距 重置表格:这样表格数据只占用它所需的空间 保留了行内间距:因此,按钮和输 ...