离线应用与客户端存储

参考资料

cookie和session
细说localStorage, sessionStorage, Cookie, Session

离线检测

  • 支持离线Web应用开发是HTML5的另一个重点
  • HTML5定义了一个navigator.onLine属性,这个属性值为true表示设备能上网,值为false表示设备离线
  • 当网络从离线变为在线/从在线变为离线触发事件:
    EventUtil.addHandler(window, "online", function () {
      //handle
    });
    EventUtil.addHandler(window, "offline", function () {
      //handle
    })
    

    应用缓存

  • HTML5的应用缓存appcache是专门为开发离线Web应用而设计的,Appcache就是从浏览器的缓存中分出来的一块缓存区,可以用一个描述文件(manifest.file)列出要下载和缓存的资源,一个示例:
    CACHE MANIFEST
    #Comment
    file.js
    file.css
    
  • 关联文件与页面
    <html  manifest="/offline.manifest">
    
  • 构成
    • 名称:唯一确定的,不区分大小写
    • 值:储存在cookie中的字符串值,值必须被URL编码
    • 域:cookie对于哪个域是有效的;Domain
    • 路径:对于指定域中的路径;Path
    • 失效时间:表示cookie应该合适删除的时间戳,默认情况下浏览器会话结束时即将所有cookie删除;自己设置删除时间GMT格式的日期;expires/Max-Age
    • 安全标志:制定后,cookie只有在使用SSL连接时才发送到服务器;Secure;
    • 限制:客户端无法更改Cookie,客户端设置cookie时不能使用这个参数,一般是服务器端使用;HttpOnly
  • 设置cookie响应报文示例:
    HTTP/1.1 200 0K
    Content-type: text/html
    Set-Cookie: name=value; expires=Mon, 22-Jan-07 07:10:24 GMT;domain=.wrox.com;secure;path=/
    other=header: other-header-value
    

Cookie与Session

  • http协议的无状态:HTTP是一种无状态协议,无状态指的是服务端对于客户端每次发送的请求都认为它是一个新的请求,上次会话和下次会话没有关系;也就是说在一个连接中,客户端可以向服务端发送多次请求,但是各个请求之间没有什么联系;
  • 持久连接:
    • HTTP/1.0的keep-alive:每次发送一个HTTP请求会附带一个connection:keep-alive声明一个持久连接
    • HTTP/1.1的persistent:持久连接是默认开启的,只有首部中包含connection:close,才会事务结束后关闭连接
  • session是在无状态的HTTP下,服务端记录用户状态用与标识具体用户的机制。它是在服务端保存的用来跟踪用户的状态的而数据结构,可以保存在文件、数据库或者集群中;
  • cookie和session机制:当服务器收到请求需要创建session对象时,首先会检查客户端请求中是否包含sessionid。如果有sessionid,服务器将根据该id返回对应session对象。如果客户端请求中没有sessionid,服务器会创建新的session对象,并把sessionid在本次响应中通过Set-Cookie的头部字段,在本地客户端设置一个cookie;当用户再次访问服务器的时候,http请求报文会附带cookie发送,cookie中保存sessionID信息来标识是否属于同一次会话;如果用户禁用cookie,则要使用URL重写,可以通过response.encodeURL(url) 进行实现;API对encodeURL的结束为,当浏览器支持Cookie时,url不做任何处理;当浏览器不支持Cookie的时候,将会重写URL将SessionID拼接到访问地址后
  • cookie是客户端保存状态;session是以服务端保存状态;

Web存储机制

  • Storage类型:提供最大的存储空间来存储名值对
    • 方法:
      • getItem(name)
      • key(index)
      • removeItem(name)
      • setItem(name, value)
  • sessionStorage 对象:存储特定某个会话的数据,也就是该数据只保存到浏览器关闭
  • globalStorage 对象:跨越会话存储数据,但是有访问限制;使用时需要指定可访问的域
    globalStorage["wrox.com"].name = "Nicholas";
    var name = globalStorage["wrox.com"].name;
    globalStorage[location.host].name = "Nicholas";
    
  • localStorage 对象:要访问同一个localStorage对象,页面必须来袭同一个域名(子域名无效)
    function getLocalStorage() {
      if(typeof localStorage == "object") {
        return localStorage;
      } else if (typeof globalStorage == "object") {
        return globalStorage[location.host];
      } else {
        throw new Error("Local storage not available.");
      }
    }
    

区分

  • localStorage 和 sessionStorage
    • 共同点:存储一般为5M;受同源策略限制;仅在客户端保存,不参与和服务器的通信;
    • 生命周期:localStorage存储的数据是永久性的,除非人为删除;sessionStorage存储的数据与标签页有效期是相同的,窗口或者标签页关闭就会删除;
    • 作用域:localStorage同一浏览器的同源文档之间共享数据;sessionStorage同一浏览器的同一窗口的同源文档之间共享数据

IndexedDB

  • 在浏览器中保存结构化数据的一种数据库,支持查询和搜索
  • 打开数据库例子:
    var request, database;
    request = indexedDB.open("admin");
    request.onerror = function (event) {
      console.log("something bad hanppened while trying to oprn: " + event.target.errorCode);
    };
    request.onsuccess = function (event) {
      database = event.target.result;
    }
    
  • 设定版本号
    if(database.version != "1.0") {
      request = database.setVersion("1.0");
      request.onerror = function (event) {
        console.log("something bad happened while trying to set version:" + event.target.errorCode);
      };
      requset.onsuccess = function (event) {
        console.log("Database initialization complete. Database name: " + database.name + ", Version: " + database.version);
      };
    } else {
      console.log("Database already initialized. Database name: " + database.name + ", Version: " + database.version);
    }
    
  • 对象存储空间
    var store = db.createObjectStore("users", {keyPath: "username"});
    var i = 0, len = users.length;//users中保存着一批用户对象
    while (i < len) {
      store.add(users[i++]);
    }
    
  • 事务
    var transaction = db.transaction();
    //只载入users存储空间中的数据
    var transaction = db.transaction("users");
    // 访问多个存储空间
    var transaction = db.transaction("users", "anotherStore");
    // 默认为只读方式访问数据,要修改访问方式,需传入第二个参数
    var IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction;
    var transaction = db.transaction("users", IDBTransaction.READ_WRITE);
    // 事务请求
    var request = db.transaction("users").objectStore("users").get("007");
    request.onerror = function (event) {
      console.log("did not get the object");
    };
    request.onsuccess = function (event) {
      var result = event.target.result;
      console.log(result.firstName);
    }
    

  转载请注明: Blog 离线应用与客户端存储

 上一篇
清除浮动方法总结 清除浮动方法总结
参考资料 CSS-清除浮动 理解当容器的高度自适应,且容器的内容中有浮动的元素,在这种情况下,容器的高度不能自动伸长以适应内容的高度,使得内容溢出到容器外面而影响(甚至破坏)布局的现象。这个现象叫浮动溢出,为了防止这个现象的出现而进行的C
2018-09-13
下一篇 
Vue踩坑合集 Vue踩坑合集
配置篇 对ES6/7语法的支持ES6模块的动态加载是我们经常用到的。在项目中,我们经常看到的一个报错就是Unexpexted token import,我们要注意import和export是ES6的新特性。通常的解决方法是引入babel-p
2018-09-12
  目录