高级程序设计(第3版)第二十三章离线应用与客户端存储/笔记

离线应用与客户端存储

离线检测

  • 开发离线应用的第一步是要知道设备是在线还是离线
  • navigator.onLine 属性,属性值为 true 表示设备能上网,值为 false 表示设备离线。
  • HTML5 还定义了两个事件: online 和 offline。
    • 当网络从离线变为在线或者从在线变为离线时,分别触发这两个事件
EventUtil.addHandler(window, "online", function(){
  alert("Online");
}); 
EventUtil.addHandler(window, "offline", function(){
  alert("Offline");
}); 
//为了检测应用是否离线,在页面加载后,好先通过 navigator.onLine 取得初始的状态。
//然后, 就是通过上述两个事件来确定网络连接状态是否变化。

 

应用缓存

  • 应用缓存(Appcache)就是从浏览器的缓存中分出来的一块缓存区
  • 要想在这个缓存中保存数据,可以使用一个 描述文件(manifest file)
  • 要将描述文件与页面关联起来,可以在<html>中的 manifest 属性中指定这个文件的路径
//描述文件示例
CACHE MANIFEST 
#Comment 
 
file.js 
file.css 
//示例结束
//指定路径
<html manifest="/offline.manifest"> 

 

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

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

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

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

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

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

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

  • 应用缓存还有很多相关的事件,表示其状态的改变。以下是这些事件。

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

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

     noupdate:在检查描述文件发现文件无变化时触发。

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

     progress:在文件下载应用缓存的过程中持续不断地触发。

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

     cached:在应用缓存完整可用时触发。

    • 一般来讲,这些事件会随着页面加载按上述顺序依次触发。
    • 不过,通过调用 update()方法也可以 手工干预,让应用缓存为检查更新而触发上述事件。
applicationCache.update(); 
//update()一经调用,应用缓存就会去检查描述文件是否更新(触发 checking 事件),
//然后就像页面刚刚加载一样,继续执行后续操作

 

数据存储

  • Cookie

    这个 HTTP响应设置以 name 为名称、以 value 为值的一个 cookie

    • 限制
      • cookie在性质上是绑定在特定的域名下的。
      • cookie是存在客户端计算机上的,每个域的 cookie总数是有限的
      • 当超过单个域名限制之后还要再设置 cookie,浏览器就会清除以前设置的 cookie
    • cookie的构成
      • 名称:一个唯一确定cookie的名称。
        • cookie名称是不区分大小写的,名称在传送时必须是 URL 编码的
      • 值:储存在 cookie中的字符串值。值必须被 URL编码。
      • 域:cookie 对于哪个域是有效的。
      • 路径:对于指定域中的那个路径,应该向服务器发送 cookie
      • 失效时间:表示 cookie 何时应该被删除的时间戳
        • 默认情况下,浏览器会话结束时即将所有 cookie删除;不过也可以自己设置删除时间。
      • 安全标志:指定后,cookie 只有在使用 SSL 连接的时候才发送到服务器。
    • JavaScript中的 cookie
      • 在js中处理cookie有些复杂,因为众所周知的蹩脚的接口,即BOM的document.cookie属性
      • 基本的 cookie操作有三种:读取、写入和删除。它们在 CookieUtil 对象中如下表示
var socket = new WebSocket("ws://www.example.com/server.php");
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.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=" + secure;
        }
        document.cookie = cookieText;
    },
    unset:function(name,path,domain,secure){
        this.set(name,"",new Date(0),path,domain,secure);
    }
};
//设置cookie
CookieUtil.set("name","Nicholas");
CookieUtil.set("book","Professional JavaScript");

//读取
alert(CookieUtil.get("name"));  //"Nicholas"
alert(CookieUtil.get("book"));  //Professional JavaScript

//删除
CookieUtil.unset("name");
CookieUtil.unset("book");

//设置cookie,包括它的路径、域、失效日期
CookieUtil.set("name","Nicholas","/books/projs","www.wrox.com",new Date("January 1,2010"));

//删除刚设置的cookie
CookieUtil.unset("name","/books/projs","www.wrox.com");

//设置安全cookie
CookieUtil.set("name","Nicholas",null,null,null,true);
    • 子 cookie
      • 为了绕开浏览器的单域名下的 cookie数限制
    • 关于 cookie的思考  
      • 尽量少存储信息,不存储敏感信息

 

  • IE用户数据
  • Web存储机制
    • 两个主要目标是:

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

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

    • 包含了两种对象的定义:sessionStorage 和 globalStorage
    • Storage 类型
      • 只能存储字符串。非字符串的数据在存储之前会被转换成字符串。

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

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

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

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

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

      • 还可以使用 length 属性来判断有多少名值对儿存放在 Storage 对象中
    • sessionStorage 对象
      • 该数据只保持到浏览器关闭。
    • globalStorage 对象  
      • 如果不使用 removeItem()或者 delete 删除,或者用户未清除浏览器缓存,存储在 globalStorage 属性中的数据会一直保留在磁盘上。
    • localStorage 对象
      • 要访问同一个 localStorage 对象,页面必须来自同一个域名(子域名无效),使用同一种 协议,在同一个端口上
      • 数据保留到通过 JavaScript 删除或者是用户清除浏览器缓存。
    • storage 事件
      • 对 Storage 对象进行任何修改,都会在文档上触发 storage 事件。
      • 即当通过属性或 setItem()方 法保存数据,使用 delete 操作符或 removeItem()删除数据,或者调用 clear()方法时,都会发生该事件。
  • IndexedDB

    在浏览器中保存结构化数据的一种数据库。

    但它的数据不是保存在表中,而是保存 在对象存储空间中

    • 数据库
      • 即把要打开的数据库名传给 indexDB.open()。
      • 传入的 数据库已经存在则就会发送一个打开它的请求;不存在,则发送一个创建并打开它的请求
    • 对象存储空间
    • 事务
      • 在数据库对象上调 用 transaction()方法可以创建事务。
    • 使用游标查询
      • 在需要检索多个对象的情况下,则需要在事务内 部创建游标。
    • 键范围
      • 通过游标查找数据的方式很有限。键范围(key range)为使用游标增添了一些灵活性。
      • 键范围由 IDBKeyRange 的实例表示。
    • 设定游标方向
    • 索引
      • 索引是为了提高查询速度而基于特定的属性创建的。
    • 并发问题 
原文地址:https://www.cnblogs.com/isremya/p/13393659.html