浏览器的「Web存储」与「应用缓存」

HTML5 在客户端存储上推出的两种新方法。之前都是由cookie完成, 但是cookie并不适合做大量数据的存储,严重影响数据传输效率。但cookie能实现跨域(在请求上由请求决定),而他们不能,这里先不谈这点。

* Web存储有两种方式: localStorage 和 sessionStorage

localStorage定义

 网上常解释:localStorage 用于持久化的本地存储,除非主动删除数据,否则数据是永远不会过期。总感觉还没明白,我理解是:localStorage 是一种持久化的存储,它能将数据存储到本地硬盘当中,因此数据没有时间限制,不会因为一次会话结束或关机等操作而消失,除非我们主动清除。

localStorage 的使用

localStoragesetItem()方法来设置值,用 getItem() 方法获取值。
html代码

<div id="result"></div>

javascript代码

// 检查浏览器支持性
if ( typeof(Storage)  && typeof(localStorage) ) {
  // 添加值
  localStorage.setItem("sayHi", "Hello World!");
  // 取值
  document.getElementById("result").innerHTML = localStorage.getItem("sayHi");
} else {
  document.getElementById("result").innerHTML = "您的浏览器不支持 Web Storage ...";
}

效果展示


代码解释: typeof(Storage) 将输出functiontypeof(localStorage) 将输出Object,也有说要添加 typeof(window.localStorage)的。增强检测,我觉得没太大必要。另外,localStorage其实就是一个对象,因此我们存储,都是往这个对象中增加键值对而已。

localStorage数据的“全局性“

  此处说全局性,大家可别以为是全局变量,这是不同的概念。localStorage的数据就数据本身来说,其实是脱离程序而存在的(磁盘中不同的程序所产生的localStorage会被分离存放,不会互相干扰),那么,它就不受程序作用域范围的限制,即,拥有全局性。既然如此,我们可以有以下用法:

统计用户页面访问次数
html代码

<div class="box">
  <p>当前访问人次:<span id="views"></span></p>
  <p>TIP:关闭或刷新,访问次数会增加。</p>
</div>

javascript代码

if (localStorage.views) {
  localStorage.views = Number(localStorage.views) + 1;
} else {
  localStorage.setItem("views", 1);
}

document.getElementById("views").innerHTML = localStorage.views;

效果展示


sessionStorage 定义

 关于sessionStorage的解释都比较统一:sessionStorage方法 针对一个 session【会话】进行数据存储。当用户关闭浏览器窗口后,数据会被删除。sessionStorage数据信息是存储在内存中的。

sessionStorage 的使用

sessionStoragelocalStorage的用法类似,也有setItem()getItem()

 下面我们来看一个案例
html代码

<div class="box">
  <button id="click">点击计数</button>
  <p>当前计数:<span id="views"></span></p>
</div>

javascript代码

if (sessionStorage.views) {
  // todo
} else {
  sessionStorage.setItem("views", 1);
}
document.getElementById("click").onclick = function() {
  sessionStorage.views = Number(sessionStorage.views) + 1;
  document.getElementById("views").innerHTML = sessionStorage.views;
}

效果展示

在该案例中,我们用dom操作给 views 绑定了点击事件,每次点击,增加一个计数,变量存放在session中。

验证什么是一次「会话」

看这个例子
html代码

<div class="box">
  <button id="click">点击计数</button>
  <p>当前访问人次:<span id="views"></span></p>
  <p>TIP:刷新,访问次数会增加;关闭页面,访问次数会重置。</p>
</div>

javascript代码

if (sessionStorage.views) {
  sessionStorage.views = Number(sessionStorage.views) + 1;
} else {
  sessionStorage.setItem("views", 1);
}

document.getElementById("views").innerHTML = sessionStorage.views;

效果展示



 所以说:一次会话是指:用户打开浏览器,点击多个超链接,访问Web服务器上的资源,然后关闭浏览器,整个过程称之为一次会话。也就是说,刷新不会提前关闭会话

关于浏览器存储,大致就这些,接下来我们在看看浏览器缓存

* 应用缓存 - 浏览器缓存

什么是应用缓存?

「缓存」 就是当你打开一个网页时,浏览器会自动下载副本到本地电脑上,感觉就像是你“另存为“一个网页到某个地方。浏览器也不是把所有的网页都缓存到本地,一般htmlget请求会缓存,而post就不缓存。

控制是否缓存

1. 客户端是否需要缓存能够在服务器端的 响应头上控制,响应头告诉缓存器不要保留缓存,缓存器就不会缓存相应内容;
2. 如果请求信息是需要认证或者安全加密的,相应内容也不会被缓存;

HTML 5 缓存

HTML 5引入了应用缓存【Application Cache】,它能实现在没有因特网连接时进行访问。它有三个优势:

  • 离线浏览 - 用户可以在应用离线时使用它们。
  • 速度 - 已缓存资源加载速度更快。
  • 减少服务器负载 - 浏览器将只从服务器上下载更新过或更改过的资源。

如果需要启用应用程序缓存,请在文档的<html>标签中包含 manifest 属性:

<DOCTYPE HTML>
<html manifest="demo.appcache">
...
</html>

如上指定了manifest的html文件将会被缓存,未对其进行指定的页面不被缓存。也可以在manifest文件中直接指定该页面。
manifest文件的建议拓展名为.appcache
请注意, manifest 文件需要配置正确的MIME-type,即"text/cache-manifest"必须在 web服务器上进行配置。


MANIFEST.appcache 文件

 manifest 文件是简单的文本文件,结构非常简单,它告知浏览器什内容需要缓存,什么内容不需要缓存。
由以下三个部分构成:

  • CACHE MANIFEST - 在此目录下列出的文件将在首次下载后进行缓存。
  • NETWORK - 在此标题下列出的文件需要与服务器交互获取,不进行缓存。
  • FALLBACK - 该标题下列出的文件规定当页面无法访问时的回退页面(比如404页面)
  • manifest文件完整实例*:
CACHE MANIFEST
# 2012-02-21 v1.0.0
/theme.css
/logo.fig
/main.js

NETWORK:
login.html

FALLBACK:
/html5/ /404.html    // 前者是资源URI, 后者是代替页面

说明:

  • 以 # 开头的是注释行,但也可以满足其他需求。应用缓存会在器 manifest 文件被更改的时候更新。如果您编辑了一副图片,或者修改了一个javascript函数,这些改变都不会被重新缓存。这时候,更新注释行中的日期和版本号是一种使浏览器重新缓存文件的非常好的办法
  • NETWORK 可以使用星号来指示所有其他资源/文件都需要因特网连接,如
NETWORK:
*
  • 更新缓存:
    1. 用户在浏览器上自己清空缓存。
    2. manifest 文件被修改。
    3. 由程序来更新应用缓存。
经常遇到的困扰:

  一旦文件被缓存,则浏览器会继续展示已缓存的版本。你可能会遇到,服务器上已经更新了代码,但浏览器依旧显示旧的内容,而且已经向CDN多次推新的资源也没用。 其实这时候就是因为浏览器缓存了的原因。你需要更新一下manifest文件。一般浏览器设置的限制缓存是5M。

* 从浏览器角度看缓存

借用网络上的一张图片:



我们来细说两个校验参数:

Last-Modified 和 ETag

1. Last-Modified 工作原理
 在浏览器第一次请求某一个URL时,服务器端的返回状态会是200,内容是你请求的资源,同时有一个Last-Modified的属性标记(HttpReponse Header)此文件在服务期端最后被修改的时间.
格式:Last-Modified:Tue, 24 Feb 2009 08:01:04 GMT

 客户端第二次请求此URL时,根据HTTP协议的规定,浏览器会向服务器发送If-Modified-Since报头(HttpRequest Header),询问该时间之后文件是否有被修改过:
格式:If-Modified-Since:Tue, 24 Feb 2009 08:01:04 GMT

 如果服务器端的资源没有变化,则自动返回HTTP304(NotChanged.)状态码,内容为空,这样就节省了传输数据量。当服务器端代码发生改变或者重启服务器时,则重新发出资源,返回和第一次请求时类似。从而保证不向客户端重复发出资源,也保证当服务器有变化时,客户端能够得到最新的资源。

注:如果If-Modified-Since的时间比服务器当前时间(当前的请求时间request_time)还晚,会认为是个非法请求。

2. ETag 工作原理
 HTTP协议规格说明定义ETag为“被请求变量的实体标记”,简单说即服务器响应时给请求URL标记,并在HTTP响应头中将其传送到客户端,类似服务器端返回的格式:
格式:Etag:“5d8c72a5edda8d6a:3239″

 客户端的查询更新格式是这样的:
格式:If-None-Match:“5d8c72a5edda8d6a:3239″
如果ETag没改变,则返回状态304。
即:在客户端发出请求后,HttpReponse Header中包含Etag:“5d8c72a5edda8d6a:3239″标识,等于告诉Client端,你拿到的这个的资源有表示ID:5d8c72a5edda8d6a:3239。当下次需要发Request索要同一个URI的时候,浏览器同时发出一个If-None-Match报头(Http RequestHeader)此时包头中信息包含上次访问得到的Etag:“5d8c72a5edda8d6a:3239″标识。
格式:If-None-Match:“5d8c72a5edda8d6a:3239“

 这样,Client端等于Cache了两份,服务器端就会比对2者的etag。如果If-None-Match为False,不返回200,返回304(Not Modified) Response。

就介绍这些,如果有错误,欢迎指正。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,458评论 4 363
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,454评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,171评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,062评论 0 207
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,440评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,661评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,906评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,609评论 0 200
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,379评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,600评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,085评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,409评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,072评论 3 237
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,088评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,860评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,704评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,608评论 2 270

推荐阅读更多精彩内容