Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >HTML5离线应用与客户端存储

HTML5离线应用与客户端存储

作者头像
laixiangran
发布于 2018-07-25 06:27:42
发布于 2018-07-25 06:27:42
3.9K00
代码可运行
举报
文章被收录于专栏:前端布道前端布道
运行总次数:0
代码可运行

支持离线 Web 应用开发是 HTML5 的另一个重点。所谓离线 Web 应用,就是在设备不能上网的情况下仍然可以运行的应用。

开发离线Web 应用需要几个步骤。首先是确保应用知道设备是否能上网,以便下一步执行正确的操作。然后,应用还必须能访问一定的资源(图像、Javascript、CSS等),只有这样才能正常工作。最好,必须有一块本地空间用户保存数据,无论能否上网都不妨碍读写。

HTML5 及其相关的 API让开发离线应用成为现实。

离线检测

要知道设备是否在线还是离线,HTML5 定义了一个 navigator.onLine 属性,这个属性值为 true 表示设备能上网,值为 false 表示设备离线。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
if (navigator.onLine) {
    // 正常工作
} else {
    // 执行离线状态时的任务
}

由于 navigator.onLine 存在一定的兼容性问题,因此除了 navigator.onLine 属性之外,为了更好地确定网络是否可用,HTML5 还定义了两个事件 online 和 offline。

当网络在离线和在线之间切换时在 window 对象上触发这两个事件:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
window.addEventListener('online', function() {
    // 正常工作
});

window.addEventListener('offline', function() {
    // 执行离线状态时的任务
});

在实际应用中,最好在页面加载后,最好先通过 navigator.onLine 取得初始的状态。然后通过上述两个事件来确定网络连接状态是否变化。当上述事件触发时,navigator.onLine 属性的值也会改变,不过必须要手工轮询这个属性才能检测到网络状态的变化。

应用缓存

HTML5 的应用缓存(application cache),或者简称为 appcache,是专门为开发离线 Web 应用而设计的。Appcache 就是从浏览器的缓存中分出来的一块缓存区。要想在这个缓存中保存数据,可以使用一个描述文件(manifest file),列出要下载和缓存的资源。描述文件示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
CACHE MANIFEST
# Comment

file.js
file.css

然后在 html 中引用:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<html manifest="./xxx.manifest">

xxx.manifest 文件的 MIME 类型必须是 text/cache-manifest。

该 API 的核心是 applicationCache 对象,这个对象有一个 status 属性,属性的值是常量,表示应用缓存的如下当前状态:

  • 0: 无缓存,即没有与页面相关的应用缓存
  • 1: 闲置,即应用缓存未得到更新
  • 2: 检查中,即正在下载描述文件并检查更新
  • 3: 下载中,即应用缓存正在下载描述文件中指定的资源
  • 4: 更新完成,即应用缓存已经更新了资源,而且所有资源都已下载完毕,可以通过 swapCache() 来使用了
  • 5: 废弃,即应用缓存的描述文件已经不存在了,因此页面无法再访问应用缓存

相关事件:

  • checking: 在浏览器为应用缓存查找更新时触发
  • error: 在检查更新或者下载资源期间发生错误时触发
  • noupdate: 在检查描述文件发现文件无变化时触发
  • downloading: 在开始下载应用缓存资源时触发
  • progress: 在文件下载应用缓存的过程中持续不断地触发
  • updateready: 在页面新的应用缓存下载完毕且可以通过 swapCache() 使用时触发
  • cached: 在应用缓存完整可用时触发

一般来讲,这些事件会随着页面加载按上述顺序依次触发。也可以通过调用 update() 方法手动触发上述事件。

数据存储

Cookie

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
HTTP/1.1 200 OK
Content-type: text/html
Set-Cookie: name=value
Other-header: other-header-value

然后浏览器 Set-Cookie 的会话信息,之后为每个请求添加 Cookie HTTP 头将信息发送回服务器,如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
GET /index.html HTTP/1.1
Cookie: name=value
Other-header: other-header-value

发送回服务器的额外信息可以用于唯一验证客户来自于发送的哪个请求。

完整的 cookie 包括:

  • 名称: 一个唯一确定 cookie 的名称。必须被 URL 编码。
  • 值: 存储在 cookie 中的字符串值。必须被 URL 编码。
  • 域: cookie 对于哪个域是有效的。
  • 路径: 对于指定域中的那个路径,应该向服务器发送 cookie。
  • 失效时间: 表示 cookie 何时应该被删除的时间戳。
  • 安全标志: 指定后,cookie 只有在使用 SSL 连接的时候才发送到服务器。
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Set-Cookie:name=value; domain=www.laixiangran.cn; path=/; expires=Mon, 29 Oct 2018 03:53:10 GMT; secure;
基本用法

在 JavaScript 中操作 cookie 有些复杂,这是因为 document.cookie 属性在不同的使用方式中表现出不同的行为。

当用来获取属性值时,document.cookie 返回当前页面可用的所有 cookie 字符串,一系列由分号隔开的键值对,如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
document.cookie
// name1=value1;name2=value2;name3=value3;

当用来设置值时,document.cookie 属性会设置一个新的 cookie 字符串添加到现有的 cookie 集合中,并不会像普通对象设置属性一样覆盖原 cookie 的值,除非设置的 cookie 的名称已经存在,如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// cookie 的名称不存在
document.cookie = 'name4=value4'
// name1=value1;name2=value2;name3=value3;name4=value4;
// 而不是 name4=value4;

// cookie 的名称存在
document.cookie = 'name3=value4'
// name1=value1;name2=value2;name3=value4;

从上面的代码我们可以看出,我们要读取或者修改或者删除指定 cookie 的值都不是很直观方便,因此我们可以封装一些方法,方便我们对 cookie 的操作:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
var CookieUtil = {

    get: function (name) {
        var cookieName = encodeURIComponent(name) + "=",
            cookieStart = document.cookie.indexOf(cookieName),
            cookieValue = null,
            cookieEnd;

        if (cookieStart > -1) {
            cookieEnd = document.cookie.indexOf(";", cookieStart);
            if (cookieEnd == -1) {
                cookieEnd = document.cookie.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);
    }

};

使用方法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 设置 cookie
CookieUtil.set('name', 'lai');
CookieUtil.set('sex', 'man');

// 读取 cookie
CookieUtil.get('name'); // 'lai'
CookieUtil.get('sex'); // 'man'

// 删除 cookie
CookieUtil.unset('name');
CookieUtil.unset('sex');

// 设置 cookie,包括它的路径、域、失效日期
CookieUtil.set('name', 'lai', '/', 'www.laixiangran.cn', new Date());
大小限制
  • 每个域的 cookie 总数是有限,不同浏览器之间所有不同,IE6 以下是最多 20 个,IE7 以上最多 50 个,Firefox最多 50 个,Opera 最多 30 个,Safari 和 Chrome 不限制。
  • cookie 的尺寸也有限制,大多数浏览器有大约 4096B。

Web Storage

Web Storage 的目的是克服由 cookie 带来的一些限制,当数据需要被严格控制在客户端上时,无须持续地将数据发回服务器。Web Storage 的两个主要目标是:

  • 提供一种在 cookie 之外存储会话数据的路径。
  • 提供一种存储大量可以跨会话存在的数据的机制。

Web Storage 主要定义了两种对象:sessionStorage 和 localStorage,是 Storage 对象的实例,这两个对象区别如下:

  • sessionStorage: 存储特定于某个会话的数据,也就是该数据只保持到浏览器关闭。存储数据大小大多数限制在 2.5M,少数浏览器限制在 5M 或者不限制。
  • localStorage: 数据保存到通过 JavaScript 删除或者是用户清除浏览器缓存。存储数据大小大多数限制在 5M,少数浏览器限制在 2.5M 或者不限制。

Storage 类型有如下方法:

  • clear(): 删除所有值。
  • getItem(name): 根据指定的名字 name 获取对应的值。
  • key(index): 获取 index 位置处的值的名字。
  • removeItem(name): 删除由 name 指定的键值对。
  • setItem(name, value): 为指定的 name 设置一个对应的值,值为字符串。

对 sessionStorage 和 localStorage 进行操作都会触发 storage 事件,该事件对象有以下属性:

  • domain: 发生变化的存储空间的域名。
  • key: 设置或者删除的键名。
  • newValue: 如果是设置值,则是新值;如果是删除键,则是null。
  • oldValue: 键被更改之前的值。

IndexedDB

Indexed Database API,简称为 IndexedDB,是在浏览器中保存结构化数据的一种数据库。其思想是创建一套 API,方便保存和读取 JavaScript 对象,同时还支持查询和搜索。

IndexedDB 设计的操作完全是异步进行的。因此,大多数操作会以请求方式进行。

基本用法
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
var indexedDB = window.indexedDB || window.msIndexedDB || window.mozIndexedDB || window.webkitIndexedDB, // 获取 indexedDB
    request,
    store,
    database,
    users = [
        {
            username: "007",
            firstName: "James",
            lastName: "Bond",
            password: "foo"
        },
        {
            username: "ace",
            firstName: "John",
            lastName: "Smith",
            password: "bar"
        }
    ];

// 打开数据库
request = indexedDB.open("example");

// 注册 onerror 及 onsuccess 事件
request.onerror = function (event) {
    alert("Something bad happened while trying to open: " + event.target.errorCode);
};
request.onsuccess = function (event) {
    database = event.target.result;

    // 操作数据库
    initializeDatabase();
};

function initializeDatabase() {
    if (database.version != "1.0") {

        // 设置数据库版本号
        request = database.setVersion("1.0");
        request.onerror = function (event) {
            alert("Something bad happened while trying to set version: " + event.target.errorCode);
        };
        request.onsuccess = function (event) {

            // 使用 users 创建对象存储空间
            store = database.createObjectStore("users", {keyPath: "username"});
            var i = 0,
                len = users.length;

            while (i < len) {

                // 插入新值
                store.add(users[i++]);
            }

            alert("Database initialized for first time. Database name: " + database.name + ", Version: " + database.version);
        };
    } else {
        alert("Database already initialized. Database name: " + database.name + ", Version: " + database.version);

        // transaction() 创建事务,objectStore() 将存储空间传入事务
        request = database.transaction("users").objectStore("users").get("007");
        request.onsuccess = function (event) {
            alert(event.target.result.firstName);
        };
    }
}
限制
  • 和 Web Storage类似,只能由同源(相同协议、域名和端口)页面操作,因此不能跨域共享信息。
  • Firefox 大小上限为 50M,移动端的 Firefox 大小上限为 5M,不允许本地文件访问。
  • Chrome 大小上限为 5M,允许本地文件访问。
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-05-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 前端布道 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
浏览器之客户端存储
大家好,我是柒八九。我们在网络拾遗之Http缓存文章中,从网络协议的视角介绍了网站「客户端缓存」 中的HTTP缓存策略,并对「强缓存」和「协商缓存」做了较为详细的介绍。
前端柒八九
2022/08/25
2.4K0
浏览器之客户端存储
HTML5五种客户端离线存储方案
HT for Web
2018/01/03
3.2K0
HTML5五种客户端离线存储方案
JavaScript客户端存储
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
奋飛
2019/08/15
1.7K0
【缓存】HTML5缓存的那些事
在HTML5出生之前,通常在浏览器(客户端)使用cookies来存储客户端的内容;
前端修罗场
2023/10/07
4161
【缓存】HTML5缓存的那些事
HTML5学习-day02【悟空教程】
请想象你正在看一个视频下面的评论,在翻到十几页的时候,你发现一个写得稍长,但非常有趣的评论。正当你想要停下滚轮细看的时候,手残按到了F5。然后,页面刷新了,评论又回到了第一页,所以你又要重新翻一次。
Java帮帮
2018/09/29
1.7K0
HTML5学习-day02【悟空教程】
【HTML5】296- 重新复习 HTML5 的 5大存储方式
在 HTML5 规范之前,存储主要是用 cookies 。 cookies 的缺点有:
pingan8787
2019/07/25
8480
【HTML5】296- 重新复习 HTML5 的 5大存储方式
详解浏览器存储
随着移动网络的发展与演化,我们手机上现在除了有原生 App,还能跑“WebApp”——它即开即用,用完即走。一个优秀的 WebApp 甚至可以拥有和原生 App 媲美的功能和体验。WebApp 优异的性能表现,有一部分原因要归功于浏览器存储技术的提升。cookie存储数据的功能已经很难满足开发所需,逐渐被Web Storage、IndexedDB所取代,本文将介绍这几种存储方式的差异和优缺点。
浪里行舟
2022/05/13
1.2K0
详解浏览器存储
浏览器本地存储方案
浏览器本地存储方案可以分为三个方面,分别为Cookie、Web Storage、IndexedDB。
WindRunnerMax
2021/01/18
6920
客户端存储
介绍 本文是关于客户端存储(client-side storage)的。这是一个通用术语,包含几个独立但相关的 API: Web Storage、Web SQL Database、Indexed Database 和 File Access。每种技术都提供了在用户硬盘上 —— 而非通常存储数据的服务器 —— 存储数据的独特方式。这么做主要基于以下两点理由:(a)使 web app 离线可用; (b)改善性能。对于客户端存储使用情况的详细阐述,请看 HTML5Rocks 上的文章 《"离线": 这是什么意思
疯狂的技术宅
2019/03/27
1.9K0
京东一面:浏览器跨标签页通信的方式都有什么?
没错,还是京东一面的问题,首先问的是浏览器跨标签也通信的方式有什么,我答完浏览器通信通信的方式,后面就接着问 JavaScript 有什么方式的了。
winty
2024/04/15
1990
京东一面:浏览器跨标签页通信的方式都有什么?
HTML5本地存储:从入门到精通
💡 概念: HTML5本地存储是一种允许Web应用程序在用户浏览器端本地保存数据的技术,无需依赖服务器。它增强了Web应用的离线功能、个性化设置保留以及性能优化。
空白诗
2024/06/14
1270
HTML 面试要点:跨标签页通信
BroadcastChannel (opens new window) 接口代理了一个命名频道,可以让指定 origin (opens new window) 下的任意 browsing context (opens new window) 来订阅它。它允许同源的不同浏览器窗口,Tab 页,frame 或者 iframe 下的不同文档之间相互通信。通过触发一个 message 事件,消息可以广播到所有监听了该频道的 BroadcastChannel 对象。
Cellinlab
2023/05/17
1.3K0
HTML 面试要点:跨标签页通信
前端存储技术
后端常用数据库做数据存储,譬如MySql、MongoDB,缓存技术存储数据,如Redis、Memcached;
Jack Chen
2019/02/25
1.9K0
前端存储技术
深入了解浏览器存储
随着移动网络的发展与演化,我们手机上现在除了有原生 App,还能跑“WebApp”——它即开即用,用完即走。一个优秀的 WebApp 甚至可以拥有和原生 App 媲美的功能和体验。WebApp 优异的性能表现,有一部分原因要归功于浏览器存储技术的提升。cookie存储数据的功能已经很难满足开发所需,逐渐被WebStorage、IndexedDB所取代,本文将介绍这几种存储方式的差异和优缺点。
Bug开发工程师
2019/05/05
8660
深入了解浏览器存储
关于客户端存储的前端面试题总结
对于前端开发者来说,如果开发经验不够充足的话,是很难知道客户端存储其实是有很多坑的。今天就来总结一些关于客户端存储的面试题,其实参加面试时一般面试官不会问这么深入,但如果你能回答的比他期望的深入的话,
用户1687375
2018/06/08
1.2K0
JavaScript的客户端存储
  客户端存储实际上就是Web浏览器的记忆功能,通过浏览器的API实现数据存储到硬盘;
JQ实验室
2022/02/09
7680
认识浏览器缓存
关于何为前端缓存,这里结合具体实际给出一个简单的定义:在两次不同的运行时中,能够共享的数据可以成为前端缓存。如何理解两次不同的运行时呢,可以理解为两次不同的页面加载过程。比如加载A页面,得到上下文环境:RunTime1,加载B页面,得到上下文:RunTime2。这两个运行时可以共享数据Front_CacheData_AB。A页面和B页面可以同时在运行时,也可以A页关闭后再打开B页面。下图1比较形象的给出了前端缓存的这种定义~
MarsBoy
2020/06/14
1.6K0
认识浏览器缓存
探索浏览器中LocalStorage以外的高级存储机制
有没有好奇过浏览器存储中除了本地存储、会话存储以及Cookie之外的存储项分别是什么?
全栈开发日记
2024/11/23
1990
探索浏览器中LocalStorage以外的高级存储机制
html5 离线存储 地理信息与本地存储
搭建离线应用程序   ①服务器设置头信息 :     AddType text/cache-manifest .manifest   ② html标签加 :     manifest=“xxxxx.manifest”   ③写manifest文件 : 离线的清单列表     先写 : CACHE MANIFEST   FALLBACK : 第一个网络地址没获取到,就走第二个缓存的   NETWORK :无论缓存中存在与否,均从网络获取 web Workers   Work
用户1197315
2018/01/22
1.8K0
HTML5 学习总结(三)——本地存储(localStorage、sessionStorage、WebSqlDataBase、IndexedDB)
HTML5问世以后,前端加入了一个重要的功能,便是本地存储,本地存储可分为4类: Local Storage:总的存储量有所限制,并不能提供真正的检索API,数据的生命期比窗口或浏览器的生命期长,数据
张果
2018/01/03
7.7K0
HTML5 学习总结(三)——本地存储(localStorage、sessionStorage、WebSqlDataBase、IndexedDB)
相关推荐
浏览器之客户端存储
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验