首頁 >web前端 >html教學 >HTML5離線應用與客戶端儲存的實現

HTML5離線應用與客戶端儲存的實現

不言
不言原創
2018-05-05 11:25:201454瀏覽

這篇文章主要介紹了HTML5離線應用程式與客戶端儲存的實現的相關資料,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟著小編過來看看吧

支援離線 Web 應用程式開發是 HTML5 的另一個重點。所謂離線 Web 應用,就是在設備無法上網的情況下仍可運作的應用。

開發離線Web 應用程式需要幾個步驟。首先是確保應用程式知道設備是否能上網,以便下一步執行正確的操作。然後,應用程式還必須能存取一定的資源(圖片、Javascript、CSS等),只有這樣才能正常運作。最好,必須有一塊本地空間用戶保存數據,無論能否上網都不妨礙讀寫。

HTML5 及其相關的 API讓開發離線應用程式成為現實。

離線偵測

要知道裝置是否線上或離線,HTML5 定義了一個navigator.onLine 屬性,這個屬性值為true 表示設備能上網,值為false 表示設備離線。

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

由於navigator.onLine 有一定的相容性問題,因此除了navigator.onLine 屬性之外,為了更好地確定網路是否可用,HTML5 還定義了兩個事件online 和offline。

當網路在離線和線上之間切換時在window 物件上觸發這兩個事件:

window.addEventListener('online', function() {
    // 正常工作
});

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

在實際應用中,最好在頁面載入後,最好先透過navigator.onLine 取得初始的狀態。然後透過上述兩個事件來決定網路連線狀態是否變化。當上述事件觸發時,navigator.onLine 屬性的值也會改變,不過必須要手動輪詢這個屬性才能偵測到網路狀態的變化。

應用程式快取

HTML5 的應用程式快取(application cache),或簡稱為appcache,是專為開發離線Web 應用程式而設計的。 Appcache 就是從瀏覽器的快取中分出來的一塊快取區。要想在這個快取中保存數據,可以使用一個描述檔(manifest file),列出要下載和快取的資源。描述檔案範例:

CACHE MANIFEST
# Comment

file.js
file.css

然後在html 中引用:

<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 頭資訊作為回應的一部分,其中包含會話資訊。伺服器回應頭範例:

HTTP/1.1 200 OK

Content-type: text/html
Set-Cookie: name=value
Other-header: other-header- value

然後瀏覽器Set-Cookie 的會話訊息,之後為每個請求添加Cookie HTTP 頭將訊息傳回伺服器,如下所示:

GET / index.html HTTP/1.1

Cookie: name=value
Other-header: other-header-value

發送回伺服器的額外資訊可以用來唯一驗證客戶來自於傳送的哪個請求。

完整的 cookie 包括:

  1. #名稱: 一個唯一確定 cookie 的名稱。必須被 URL 編碼。

  2. 值: 儲存在 cookie 中的字串值。必須被 URL 編碼。

  3. 域: cookie 对于哪个域是有效的。

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

  5. 失效时间: 表示 cookie 何时应该被删除的时间戳。

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

复制代码

代码如下:

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 字符串,一系列由分号隔开的键值对,如下所示:

document.cookie
// name1=value1;name2=value2;name3=value3;

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

// cookie 的名称不存在
document.cookie = &#39;name4=value4&#39;
// name1=value1;name2=value2;name3=value3;name4=value4;
// 而不是 name4=value4;
// cookie 的名称存在
document.cookie = &#39;name3=value4&#39;
// name1=value1;name2=value2;name3=value4;

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

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);
    }
};

使用方法:

// 设置 cookie
CookieUtil.set(&#39;name&#39;, &#39;lai&#39;);
CookieUtil.set(&#39;sex&#39;, &#39;man&#39;);

// 读取 cookie
CookieUtil.get(&#39;name&#39;); // &#39;lai&#39;
CookieUtil.get(&#39;sex&#39;); // &#39;man&#39;

// 删除 cookie
CookieUtil.unset(&#39;name&#39;);
CookieUtil.unset(&#39;sex&#39;);

// 设置 cookie,包括它的路径、域、失效日期
CookieUtil.set(&#39;name&#39;, &#39;lai&#39;, &#39;/&#39;, &#39;www.laixiangran.cn&#39;, 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 设计的操作完全是异步进行的。因此,大多数操作会以请求方式进行。

基本用法

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,允许本地文件访问。


以上是HTML5離線應用與客戶端儲存的實現的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn