离线应用与客户端存储学习笔记

所谓的离线web应用,就是在设备上不能上网的情况下仍然可以运行的应用。

 开发离线web 应用的几个步骤:

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

2.然后应用还必须能访问一定的资源

3.最后必须有一块本地的储存空间用于保存数据

离线检测 navigator.onLine

HTML5 定义了一个navigator.onLine属性。这个属性值为true表示设备可以上网,值为false表示设备离线。

        if(navigator.onLine) {
            //正常工作
        } else {
            //执行离线状态时的任务
        }

除了navigator.onLine属性之外,HTML5还定义了两 个事件:online和offline。当网络从离线变为在线或者从在线 变为离线时,分别触发这 两个事件。

        EventUtil.addHandler(window,"online",function(){
            alert("Online");
        });
        EventUtil.addHandler(window,"offline",function(){
            alert("Offline");
        })

应用缓存

HTML5的应用缓存,或者简称为appcache,是专门为开发离线Web应用而设计的。

要想在这个缓存中保存数据,可以使用一个描述文件(manifest file),列出要下载和缓存的资源。

CACHE MANIFET
#Comment

file.js
file.css

要将描述的文件与页面关联起来,可以在<html>中的manifest属性中指定这个文件的路径,例如:

<html manifest="/offline.manifest">

这个API的核心是applicationCache对象,这个对象有一个status属性,属性值是常量:

0:无缓存

1: 闲置

2:检查中

3:下载中

4:更新完成。所有 资源下载完成后,可以通过swapCache()来使用了。

5:废弃

应用缓存还有很多相关的事件,表示其状态的改变:

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

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

noupdata:在检查描述文件发现文件无变化时触发

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

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

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

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

applicationCache.updata();

updata()一经调用,应用缓存就会去检查描述文件是否更新。然后就像页面刚刚加载一样,继续执行后续操作。如果触发了cached事件,就说明应用缓存已经准备就绪,不会再发生其他操作。如果触发了updateready事件,则说明新版本的应用缓存已经可用,而此时要调用swapCache()来启用新应用缓存。

        EventUtil.addHandler(applicationCache,"updateready",function(){
            applicationCache.swapCache();
        })

数据存储

Cookie

IE用户数据

Web存储机制

IndexedDB

Cookie

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

HTTP/1.1 200 OK
Content-type: text/html
Set-Cookie: name=value
Other-header: other-header-value

浏览器会存储这样的会话信息。并在这之后,通过为每个请求添加Cookie HTTP头部信息发送回服务器,例如:

GET /index.html HTTP/1.1
Cookie: name=value
Other-header: other-header-value

限制

IE6及更多版本最多20个cookie

IE7之后的版本每个域名最多50个cookie

Firefox限制每个域最多50个cookie

Opera限制每个域最多30个cookie

Safar和Chrome没有硬性规定

cookie组成

名称:一个惟一确定名称

值:储存在cookie中的字符串值

域:cookie对于哪个域是有效的

路径:对于指定域中的哪个 路径,应用向服务器发送cookied

失效时间:表示cookie何时应用被删除的时间戳

安全标志:指定后,cookie只有在使用SSL连接的时候才会发送到服务器。

Javascript中的cookie

所有名字和值都是经过URL编码的,所以必须使用decodeURIComponent()

当用于设置值的时候,document.cookie属性可以设置为一个新的cookie字符串。

document.cookie = "name=Nicholas";

下面例子使用encodeURI-Component()

document.cookkie = encodeURIComponent("name") + "=" + encodeURIComponent("Nicholas");

要给被创建的cookie指定额外的信息,可以如下:

document.cookkie = encodeURIComponent("name") + "=" + encodeURIComponent("Nicholas") + ";domain=.wrox.com;path=/";

基本的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.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);
     }
 }
        //设置cookie
        CookieUtil.set("name", "Nicholas");
        CookieUtil.set("book", "Professional JavaScript");

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

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

        //设置cookie 包括它的路径,域,失效日期
        CookieUtil.set("name", "Nicholas","/book/projs","www.wrox.com", new Date("January 1, 2011"));
        //删除刚刚设置的cookie
        CookieUtil.unset("name", "/book/projs", "www.wrox.com")
        //设置安全的cookie
        CookieUtil.set("name","Nicholas",null,null,null,true);

子cookie

为了绕开浏览器的单域名下的cookie限制数,可以使用一种称为子cookie的概念。它的格式如下 :

name=name1=value&name2=value2&name3=value3&name4=value4&name5=value5

获取子cookie方法有两种:get()和getAll()

设置子cookie方法有两种:set()和setAll()

删除子cookie方法有两种:unset(),unsetAll()

IE用户数据

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

    <div style="behavior:url(#default#userData)" id="dataStore"></div>


    <script type="text/javascript">
        var dataStore = document.getElementById("dataStore");
        dataStore.setAttribute("name", "Nichilas");
        dataStore.setAttribute("book", "Professional JavaScript");
        dataStore.save("BookInfo"); //保存到数据空间BookInfo

        dataStore.load("BookInfo"); //获取数据
        console.log(dataStore.getAttribute("name"));
        console.log(dataStore.getAttribute("book"));

        //可以使用removeAttribute()方法明确指定要删除的数据
        dataStore.removeAttribute("name");
        dataStore.removeAttribute("book");
        dataStore.save("BookInfo");
    </script>

Web存储机制

Web Storage的两个主要目的是:

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

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

两种对象定义:sessionStorage和globalStorage

Storage类型

Storage类型提供最大的存储空间来存储名值对,Storage的实例与其他对象类似,有以下方法:

clear():删除所有值。

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

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

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

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

sessionStorage对象

该对象存储特定于某个会话的数据,会cookie,在浏览器关闭后消失。

        //使用方法存储数据
        sessionStorage.setItem("name", "Nicholas");
        //使用属性存储数据
        sessionStorage.book = "Profesional Javascript";
        //使用方法来读取数据
        sessionStorage.getItem("name");
        //使用属性存储数据
        var book = sessionStorage.book;

还可以通过结束length属性和key()方法来迭代sessionStoragel中的值:

        for (var i = 0, len = sessionStorage.length; i < len; i++) {
            var key = sessionStorage.key(i);
            var value = sessionStorage.getItem(key);
            console.log(key + "=" + value);
        }

globalStore对象

这个对象的目的是跨越会话存储数据。

        //保存数据
        globalStorage = ["wrox.com"].name = "Nichloas";
        //获取数据
        var name = globalStorage["wrox.com"].name;

        //保存数据
        globalStorage["www.wrex.com"].name = "Nichloas";
        //获取数据
        var name = globalStorage["www.wrex.com"].name;

localStorage对象

该对象可以持久保存客户端数据的方案取代了globalStorage。

        //使用方法保存数据
        localStorage.setItem("name", "Nicholas");
        //使用属性保存数据
        localStorage.book = "Professinal Javascript";

        //使用方法读取数据
        var name = localStorage.getItem("name");
        //使用属性读取数据
        var book = localStorage.book;

storage事件

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

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

key:设置或者删除的键名

newValue:如果是设置值,则是新值,如果是删键,则是null

oldValue:键被更改之前的值

以下代码展示了如何侦听storage事件

        EventUtil.addHandler(document,"storage",function(event){
            alert("Storage changed for " + event.domain);
        })

限制

localStorage:桌面浏览器会设置每个来源5MB,浏览 器2.5MB

sessionStorage:因浏览器而异,IE和Opera5MB,其他是2.5MB

IndexedDB

Indexed Database API,简称为IndexedDB,是在浏览器中保存数据的一种数据库。

var indexedDB = window.indexedDB || window.msIndexedDB || window.mozIndexDB || window.webkitIndexedDB ;

数据库

使用Index的第一步是打开它,即要把数据库名称传给indexedDB.open()。调用indexedDB.open()会返回一个IDBRequest对象,这个对象上可以添加onerror和onsuccess事件处理即可,如下示例:

        var request,database;
        request = indexedDB.open("admin");
        request.onerror = function(event){
            alert("Something bad happened while trying to open:" + event.target.errorCode);
        }
        request.onsuccess = function(event){
            database = event.target.result;
        }

对象存储空间

在建立 数据库后,下一步是使用对象存储空间。

假设要保存用户记录由用户名,密码等组成,可如下:

        var user = {
            username: "007",
            firstName: "James",
            lastName: "Bond",
            password: "foo"
        }

以下是为保存上述用户记录而创建对象存储空间的示例:

var store = db.createObjectStore("users",{keyPath: "username"});

有了存储空间的引用,接下来可以使用add()或put()方法来向其中添加数据。

        //users 中保存着一批用户对象
        var i = 0,
        len = users.length;
        while(i<len){
            store.add(users[i++]);
        }

如果想验证请求是否成功完成,可以把返回的请求对象保存一个变量中,然后再指定onerror或onsuccess事件处理程序

        //users 中保存着一批用户对象
        var i = 0,
        request,
        len = users.length;

        while(i<len){
            request = store.add(users(i++));
            request.onerror = function(){
                //处理程序
            };
            request.onsuccess = function(){
                //处理成功
            };
            request.push(request);
            
        }

创建了对象存储空间并向其中添加数据之后,就可以查询数据了

事务

在数据库对象上调用transactioon()方法可以创建事务。

var transaction = db.transaction();
var transaction = db.transaction("users",IDBTransaction.READ_WRITE);

取得了事务的索引后,使用objectStore()方法并传入存储空间,就可以访问特定的存储空间。

add(),put(),get(),delete(),clear()

        var request = db.transaction(users).objectStore("users").get("007");
        request.onerror = function(event){
            alert("Did not get the object");
        }
        request.onsuccess = function(event){
            var result = event.target.result;
            alert(result.firstName);
        }

猜你喜欢

转载自blog.csdn.net/weixin_42659625/article/details/82826443