开发离线Web应用需要几个步骤:

首先确保应用知道设备是否能上网。

应用必须能访问一定的资源(图像,Javascript,CSS),这样才能正常工作。

离线检测

navigator.onLine

HTML5新定义的属性,这个属性值为true表示设备能上网,值为false表示离线设备。这个属性的关键是浏览器必须知道设备能否访问网络,从而返回正确的值。

相关事件类型:online和offline

HTML5还定义了两个事件:online和offline。

当网络从离线变为在线或者从在线变为离线,分别触发着两个事件。

应用缓存

HTML5的应用缓存,或者简称为appcache,是专门为开发离线Web应用而设计的。Appcache就是从浏览器缓存中分出来的一块缓存区。

要想在这个缓存中保存数据,可以使用一个描述文件(manifest file),列出要下载和缓存的资源。即使用户在离线状态下按了刷新按钮,您的应用也会正常加载和运行。

使用缓存接口可为您的应用带来以下三个优势:

离线浏览 - 用户可在离线时浏览您的完整网站

速度 - 缓存资源为本地资源,因此加载速度较快。

服务器负载更少 - 浏览器只会从发生了更改的服务器下载资源。

清单文件

清单文件必须以 text/cache-manifest MIME 类型提供

清单文件格式

CACHE MANIFEST

# 2010-06-18:v2

# Explicitly cached 'master entries'.

CACHE:

/favicon.ico

index.html

stylesheet.css

images/logo.png

scripts/main.js

# Resources that require the user to be online.

NETWORK:

login.php

/myapi

http://api.twitter.com

# static.html will be served if main.py is inaccessible

# offline.jpg will be served in place of all images in images/large/

# offline.html will be served in place of all other .html files

FALLBACK:

/main.py /static.html

images/large/ images/offline.jpg

*.html /offline.html

清单可包括以下三个不同部分:CACHE、NETWORK 和 FALLBACK。

CACHE: 这是条目的默认部分。系统会在首次下载此标头下列出的文件(或紧跟在 CACHE MANIFEST 后的文件)后显式缓存这些文件。

NETWORK:

此部分下列出的文件是需要连接到服务器的白名单资源。无论用户是否处于离线状态,对这些资源的所有请求都会绕过缓存。可使用通配符。

FALLBACK:

此部分是可选的,用于指定无法访问资源时的后备网页。其中第一个 URI 代表资源,第二个代表后备网页。两个 URI 必须相关,并且必须与清单文件同源。可使用通配符。

NOTE这些部分可按任意顺序排列,且每个部分均可在同一清单中重复出现。

引用清单文件

...

NOTE:

CACHE MANIFEST 字符串应在第一行,且必不可少。

网站的缓存数据量不得超过 5 MB。

HTTP 缓存标头以及对通过 SSL 提供的网页设置的缓存限制将被替换为缓存清单(也就是加了密的网站Are https URLs encrypted)。因此,通过 https 提供的网页可实现离线运行。

如果您要编写的是针对 Chrome 网上应用店的应用,可使用 unlimitedStorage 取消该限制。

如果清单文件或其中指定的资源无法下载,就无法进行整个缓存更新进程。在这种情况下,浏览器将继续使用原应用缓存。

applicationCache对象

applicationCache对象有一个status属性,属性的值是常量,表示应用缓存的状态。

applicationCache.status

0:无缓存,即没有与页面相关的应用缓存

1:闲置,即应用缓存未得到更新

2:检查中,即正在下载描述文件并检查更新

3:下载中,即应用缓存正在下载描述文件中指定的资源

4:更新完成,即应用缓存已经更新了资源,而且所有资源都已下载完毕,可以通过swapCache()来使用了

5:废弃,即应用缓存的描述文件已经不存在了,因此页面无法再访问应用缓存

相关事件类型

checking:在浏览器为应用缓存查找更新时触发

error:在检查更新或下载资源期间发生错误时触发

noupdate:在检查描述文件无变化时粗放

downloading:在开始下载应用缓存时资源时触发

progress:在文件下载应用缓存资源时粗放

updateready:在页面新的应用缓存下载完毕,而且可以通过swapCache()时触发。

Cookie

HTTP cookie,通常叫做cookie,最初是在客户端用于存储会话信息的。该标准要求服务器的任意HTTP请求发送Set-Cookie HTTP头部作为响应的一部分,其中包含会话信息。

// HTTP响应

HTTP/1.1 200 OK

Content-type: text/html

Set-cookie: name=value

Other-header: other-header-value

// HTTP请求

GET /index.html HTTP/1.1

Cookie: name=value

Other-header: other-header-value

第一段会话过程

服务器:设置name=value的cookie,并将其作为响应头部的一部分,发送给浏览器。

浏览器:储存name=value的cookie并将其作为请求头的一部分,发送给服务器。

NOTE:

会话过程的名称和值都是经过URL编码的。

每个域的cookie总数是有限的,不同浏览器之间各有不同。当超过单个域名限制之后还有再设置cookie,浏览器就会清除以前的cookie。

cookie在性质上是绑定在特定域名下的。当设定一个cookie后,再给创建它的域名发送请求时,都会包含这个cookie。

cookie构造

// HTTP响应

HTTP/1.1 200 OK

Content-type: text/html

Set-cookie: name=value; expires=Mon, 22-JAN-07 07:10:24 GMT; domain=.wrox.com;path=/;secure

Other-header: other-header-value

// HTTP请求

GET /index.html HTTP/1.1

Cookie: name=value

Other-header: other-header-value

名称(name):一个唯一确定cookie的名称,cookie的名称必须是经过 URL编码的。

值(value):储存在cookie的字符串值,值必须被 URL编码。

域:cookie对于那个域是有效的。所有向该域发送的请求中都会包含这个cookie信息。如果没有明确设定,那么这个域会被认作来自设置cookie的那个域。

路径:对于指定域中的那个路径,应该向服务器发送cookie

失效时间:表示cookie应该被删除的那个时间戳

安全标志:指定后,cookie只能在SSL的连接时,才能发送到服务器

第二段会话过程

服务器:设置name=value的cookie,同时告诉浏览器

它会在格林威治时间2007年1月22日7:20:24失效。

对于所有wrox.com的子域和域名下(由path参数指定的)都有效

同时通过SSL连接才能传输。

并将其作为响应头部的一部分,发送给浏览器。

浏览器:储存name=value的cookie并将其作为请求头的一部分,发送给服务器。

Note:后四个,域/路径/失效时间/安全标志都是 服务器给浏览器的指示。以指定何时该发送cookie。这些参数并不会作为发送到服务器的标志,名值对才会被发送。只有cookie的名字和值是必须的。

document.cookie

用来获取属性值时,document.cookie返回当前页面可用的(根据cookie的域,路径,失效时间和安全设置)所有的cookie的字符串。

[]()

当用来设置值得时候,document.cookie可以用来设置新的cookie字符串。这个cookie字符串会用来解释并添加到现有的cookie中。设置的值并不会覆盖cookie,除非设置的值已经存在。

var cookieUtil = {

get: function ( name ) {

var cookieName = encodeURIComponent( name ) + '=',

cookieStart = document.cookie.indexOf(cookieName),

cookieValue = null;

if( cookieStart > -1 ) {

var cookieEnd = document.cookie.indexOf(';',cookieStart);

if( cookieEnd === -1 ) {

cookieEnd = document.length;

}

cookieValue = decodeURIComponent( document.cookie ).substring(cookieStart+cookieName.length, cookieEnd)

}

return cookieValue;

},

set: function ( name, value, expires, path, domain, secure ) {

var cookieText = encodeURIComponent(name) + '=' + encodeURIComponent(value);

if( expires instanceof Date ) {

cookieText += "; expires=" + expires.toGMTString();

}

if( path ) {

cookieText += '; path=' + path;

}

if( domain ) {

cookieText += '; domain=' + domain;

}

if( secure ) {

cookieText += '; secure';

}

document.cookie = cookieText;

},

unset: function ( name, path, domain, secure ) {

this.set( name, '' , new Date(0), path, domain, secure)

}

}

子cookie

为了绕开 浏览器 的单域名下的cookie数限制,一种开发人员使用了一种称为子cookie(subcookie)的概念。子cookie是存放在单个cookie中的更小段的数据。也就是使用cookie值来储存多个名称值对儿。

子cookie一般以查询字符串的格式进行格式化。然后这些值可以使用单个cookie进行储存和访问

name=name1=value1&name2=value2&name3=value3

上面展示了如何写入,读取和删除cookie,下面展示操作子cookie的方法。

var SubCookieUtil = {

get: function ( name, subName ) {

var cookieValue = this.getAll( name );

if( subName ) {

return result[subName];

}

else {

return null;

}

},

getAll: function ( name ) {

var cookieName = encodeURIComponent( name ) + '=',

cookieStart = document.cookie.indexOf( cookieName ),

cookieValue = null,

cookieEnd,

result = {};

if( cookieStart > -1 ) {

cookieEnd = document.cookie.indexOf( ';', cookieStart );

if( cookieEnd === -1 ) {

cookieEnd = document.cookie.length;

}

}

cookieValue = document.cookie.substring( cookieStart+cookieName.length, cookieEnd );

decodeURIComponent( cookieValue );

if( cookieValue.length > 0 ) {

subCookies = cookieValue.split( '&' );

for( var i = 0; i < subCookies.length; i++ ) {

var parts = subCookies[i].split( '=' );

result[parts[0]] = parts[1];

}

return result;

}

else {

return null;

}

},

set: function ( name, subName, value, expires, path, domain, secure ) {

var subCookies = this.getAll( name ) || {};

subCookies[subName] = value;

this.setAll( name, subCookies, expires, path, domain, secure );

},

setAll: function ( name, subCookies, expires, path, domain, secure ) {

var cookieText = encodeURIComponent( name ) + '=',

subCookiesParts = [],

subName;

for( subName in subCookies ) {

if( subCookies.hasOwnProperty( subName ) ) {

subCookiesParts.push( encodeURIComponent(subName) + '=' + encodeURIComponent(subCookies[subName]) );

}

}

if( subCookiesParts.length > 0 ) {

cookieText += subCookiesParts.join('&');

if( expires instanceof Date ) {

cookieText += '; expires=' + expires.toGMTString();

}

if( path ) {

cookieText += '; path=' + path;

}

if( domain ) {

cookieText += '; domain=' + domain;

}

if( secure ) {

cookieText += '; secure'

}

} else {

cookieText += '; expires=' + (new Date(0).toGMTString());

}

document.cookie = cookieText;

},

unsetAll: function ( name, subCookies, expires, path, domain, secure ) {

this.set( name, null, new Date(0), path, domain, secure );

},

unset: function ( name, subName, expires, path, domain, secure ) {

var subCookies = this.get( name );

if( subCookies ) {

delete subCookies[subName]

this.setAll( name, subCookies, expires, path, domain, secure );

}

}

}

关于cookie的性能与安全

由于所有的cookie都会由浏览器作为请求头发送,所以在cookie中存储大量信息会影响到特定域的请求性能。cookie信息越大,完成对服务器请求的时间也就越长。

cookie数据并非存储在一个安全环境中,其中包含的任何数据都可被他人访问。所以一定不要在cookie中储存重要和敏感的数据。

IE用户数据

在IE5.0中,微软通过一个自定义行为引入了持久化用户数据的概念。用户数据允许每个文档最多128KB数据,每个域名最多1MB数据。要使用持久化用户数据,首先,必须如下所示,使用CSS在某个元素上指定userData行为。

`

var dataStore = getElementById('dataStore');

// 写入数据

dataStore.setAttribute('name','Nicholas');

dataStore.setAttribute('book','Professional Javascript');

dataStore.save('BookInfo');

// 获取数据

dataStore.load('BookInfo');

// 访问数据

console.log(dataStore.getAttribute('name'));

console.log(dataStor.getAttribute('book'));

// 删除数据

dataStore.removeAttribute( 'name' );

dataStore.removeAttribute( 'book' );

dataStore.save('BookInfo');

Note:

和cookie一样,IE用户数据并非安全的,所有不能存放敏感信息。

用户数据默认是可以跨越会话持久存在的,同时也不会过期

要访问某个数据空间,脚本运行的页面必须来自于同一个域名,路径并使用与进行存储的脚本同样的协议。

Web存储机制

Web Storage的两个主要目标是

提供一种在cookie之外存储会话数据的途径

提供一种存储大量可以跨会话存在的数据的机制。

Note:与其他客户端储存方案相比,WebStorage同样也有限制,这些限制因浏览器围而异。一般来说,对存储空间大小的限制都是以每个来源(协议,域名,端口号)为单位的。换句话说,每个来源都要固定大小的空间用于保存自己的数据。考虑到这个限制,就要注意分析和控制每个来源中有多少页面需要保存数据。

Storage类型

Storage提供最大的空间(因浏览器而异)来储存名值对。

sessionStorage instanceof Storage // true

localStorage instanceof Storage// true

localStorage.__proto__ === Storage.prototype // true

sessionStorage.__proto__ === Storage.prototype // true

由上可知,sessionStorage对象与localStorage对象都为Storge类型的实例。因此它们都可以访问到Storage类型的原型对象上的方法。有如下这些方法。

clear():删除所有值;Firefox中没有实现

getItem(name):根据指定的名字name获取对应的值

key(index):获得index位置处的值得名字

removeItem(name):删除由name指定的名值对

setItem(nname, value):为指定的name设置一个对应的值

同时可以使用length属性判断Storage对象中有多少名值对。但无法判断对象中所有数据的大小,不过IE8提供了一个remainingSpace属性,用于获取还可以使用的存储空间的字节数。

Note:Storge类型只能存储字符串。非字符串的数据在存储之前会被转换为字符串。

sessionStorage对象

为每一个给定的源(given origin)维持一个独立的存储区域,该存储区域在页面会话期间可用(即只要浏览器处于打开状态,包括页面重新加载和恢复)。

sessionStorage对象主要用于仅针对会话的小段数据的存储。它储存特定于某个会话的数据,也就是该数据只保持到浏览器关闭。这个对象就像会话cookie,也会在浏览器关闭后消失。

存储在sessionStorage中的数据可以跨越页面而存在,同时如果浏览器支持,浏览器崩溃重启后依然可用(Firefox和Webkit都支持,IE不行)。

sessionStorage对象绑定于某个服务器会话,所有当文件在本地运行的时候是不可用的。

存储在sessionStorage的数据只能由最初给对象储存数据的的页面访问到,所以对多页面应用有限制。

// 写入数据

sessionStorage.setItem( 'name', 'Nicholas' );

// 访问数据

sessionStorage.getItem( 'name' );

// 迭代数据

for( var i = 0,len = sessionStorage.length; i < len; i++ ) {

var key = sessionStorge.key( i );

var value = sessionStorage.getItem( key );

console.log( key + '=' + value );

}

for(key in sessionStorage) {

var value = sessionStorage.getItem( key );

console.log( key + '=' + value );

}

// 删除数据

sessionStorage.removeItem( 'name' );

Note:不同浏览器写入数据的方法略有不同。Firefox和Webkit实现了同步写入,所有添加到储存空间的数据是立刻被提交的。而IE的实现是异步写入数据,所以在设置数据和将数据写入磁盘之间可能有一些延迟。对于少量数据而言,这个差异是可以忽略的。对于大量数据,你会发现IE比其他浏览器更快的恢复执行,因为它会跳过实际的磁盘写入过程。

在IE8中可强制把数据写入磁盘,如下。

// 防止代码执行的时候,不会发生其他磁盘写入操作

sessionStorage.begin();

sessionStorage.name = 'Nicholas';

// 确保name的值在调用commit()之后立刻写入磁盘

sessionStorage.commit();

localStorage对象

localStorage 同样的功能,但是在浏览器关闭,然后重新打开后数据仍然存在。

localStorage实现跨越会话存储数据,在HTML5规范中作为持久保存客户端数据的方案取代了globalStorage。

规则:要访问同一个localStorage对象,页面必须来自于同一个域名(子域名无效),使用同一种协议,在同一个端口上。

因为localStorage是Storage的实例,所有可以像使用sessionStorage一样来使用它。

storage事件

对Storage对象进行任何修改,都会在文档上触发storage事件。

storge事件对象

domain:发生变化的储存空间的域名

key:设置或者删除的键名

newVaule:如果是设置值,则为新值;如果是删除键,则为null

oldValue:键被更改之前的值

html5结构 客户端缓存,Javascript--离线应用与客户端储存相关推荐

  1. HTML5应用程序缓存实现离线Web网页或应用

    HTML5应用程序缓存和浏览器缓存的区别. (有些)浏览器会主动保存自己的缓存文件以加快网站加载速度.但是要实现浏览器缓存必须要满足一个前提,那就是网络必须要保持连接.如果网络没有连接,即使浏览器启用 ...

  2. Redis系列(十四)、Redis6新特性之RESP3与客户端缓存(Client side caching)

    Redis6引入新的RESP3协议,并以此为基础加入了客户端缓存的新特性,在此特性下,大大提高了应用程序的响应速度,并降低了数据库的压力,本篇就带大家来看一下Redis6的新特性:客户端缓存. 目录 ...

  3. HTML5 Web 客户端五种离线存储方式汇总

    为什么80%的码农都做不了架构师?>>>    最近折腾HTML5游戏需要离线存储功能,便把目前可用的几种HTML5存储方式研究了下,基于HT for Web写了个综合的实例,分别利 ...

  4. HTML5 应用程序缓存 离线浏览【Application Cache】轻松地创建 web 应用的离线版本。

    HTML5 应用程序缓存 使用 HTML5,通过创建 cache manifest 文件,可以轻松地创建 web 应用的离线版本. 什么是应用程序缓存(Application Cache)? HTML ...

  5. HTML5 - 应用程序缓存(Application Cache)

    为什么要使用Application Cache技术? 在HTML5之前,我们需要接入网络才能访问,这毫无疑问是网站多次请求服务器,造成速度变慢,对于PC用户,网络相对比较稳定,载入速度也不会差太多.但 ...

  6. 借助Service Worker和cacheStorage缓存及离线开发

    一.缓存和离线开发 说得HTML5离线开发,我们通常第一反应是使用html5 manifest缓存技术,此技术已经出现很多年了,我以前多次了解过,也见过一些实践案例,但是却从未在博客中介绍过,因为并不 ...

  7. HTML5的应用缓存

    HTML5的应用缓存(application cache),或者简称为appcache,是专门为开发离线Web应用而设计的. Appcache就是从浏览器的缓存中分出来的一块缓存区.要想在这个缓存中保 ...

  8. iOS Web应用开发:运用HTML5、CSS3与JavaScript

    <iOS Web应用开发:运用HTML5.CSS3与JavaScript> 基本信息 原书名:Pro iOS web design and development:HTML5, CSS3, ...

  9. 网页编程课程大作业实验报告HTML5 、CSS5 、JavaScript

    网页编程课程大作业实验报告 课程名称 网页编程 实验成绩 计算机学院制 一.实验内容与要求 利用HTML5 .CSS5 .JavaScript等知识,按照特定的主题制作一个完整的网站. 二.网站名称以 ...

最新文章

  1. Python经典面试题100道(附PDF下载地址)
  2. 加入 Spring 技术学习群
  3. php 发送表格,PHP邮件表格,带有使用AJAX发送的单选按钮
  4. 科大星云诗社动态20210526
  5. 大剑无锋----SpringMVC原理详细解析
  6. MySQL isnull()函数基本指南
  7. python-9:nonlocal,指定上一级变量
  8. Unity代码里的Position和界面上的Position
  9. 驻华大使亲自带货 卢旺达咖啡豆成春节热销“洋年货”
  10. Code Review
  11. 对大家的工作和职业方向有益才是我的最终目的
  12. 保护眼睛——设置WIN7和XP 窗体、Chrome、IE网页背景颜色(zz)
  13. CSS系列教程----摘自洪恩网站
  14. 中国石油大学计算机评估排名,中国石油大学华东学科评估结果及排名情况怎样...
  15. mysql数据库扫描工具_Scuba2019最新免费版|Scuba(数据库扫描工具)官方版下载_v10.0.3_9号软件下载...
  16. 电磁兼容EMC详解及测试流程
  17. 2018百度之星程序设计大赛资格赛(4道题的答案)
  18. BugKu——你必须让他停下
  19. Linux 练习 - 磁盘存储和文件系统
  20. 【我对软件平台架构的理解】第一部分:软件平台架构有什么用

热门文章

  1. (图论)51NOD 1264 线段相交
  2. Microsoft Dynamics 365 之 味全食品 项目分享和Customer Engagement新特性分享
  3. Linux学习之七--mysql的安装使用
  4. Python中pip版本升级error:You are using pip version 7.1.2, however version 8.1.1 is available.
  5. Redis缓存异常的容错实现方法( .net)
  6. go 中recover捕获异常
  7. [转] linux下shell中使用上下键翻出历史命名时出现^[[A^[[A^[[A^[[B^[[B的问题解决,Linux使用退格键时出现^H解决方法
  8. 【报告分享】2021抖音电商生态发展报告.pdf(附下载链接)
  9. 研究生必备自学课程!打好科研的数学基础与机器学习基础!
  10. instant java,Instant