HTML5 Offline Application and Client-Side Storage

Supporting offline web application development is another focus of HTML5. The so-called offline Web applications are applications that can still run even when the device cannot access the Internet.

Developing an offline web application requires several steps. The first is to make sure the app knows if the device has internet access so that it can take the correct action next. Then, the app must also have access to certain resources (images, Javascript, CSS, etc.) for it to work properly. Preferably, there must be a local space for users to save data, regardless of whether the Internet access is not hindering reading and writing.

HTML5 and its associated APIs make developing offline applications a reality.

Offline detection

To know whether the device is online or offline, HTML5 defines a navigator.onLine property. The value of this property is true to indicate that the device can access the Internet, and a value of false indicates that the device is offline.

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

Due to some compatibility issues with navigator.onLine, in addition to the navigator.onLine property, HTML5 defines two events online and offline in order to better determine whether the network is available.

These two events are fired on the window object when the network switches between offline and online:

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

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

In practical applications, it is best to obtain the initial state through navigator.onLine after the page is loaded. Then it is determined whether the network connection state changes through the above two events. When the above event fires, the value of the navigator.onLine property will also change, but this property must be polled manually to detect changes in network status.

application cache

HTML5's application cache, or appcache for short, is designed specifically for developing offline web applications. Appcache is a cache area separated from the browser's cache. To store data in this cache, use a manifest file that lists the resources to download and cache. Example of description file:

CACHE MANIFEST
# Comment

file.js
file.css

Then reference in html:

<html manifest="./xxx.manifest">

The MIME type of the xxx.manifest file must be text/cache-manifest.

The core of the API is the applicationCache object, which has a status attribute, and the value of the attribute is a constant, indicating the current state of the application cache as follows:

  • 0: No cache, i.e. there is no application cache associated with the page
  • 1: Idle, i.e. the app cache is not updated
  • 2: Checking, that is, downloading the description file and checking for updates
  • 3: Downloading, that is, the application cache is downloading the resources specified in the description file
  • 4: The update is complete, that is, the application cache has updated the resources, and all the resources have been downloaded, and can be used through swapCache()
  • 5: Abandoned, that is, the description file of the application cache no longer exists, so the page can no longer access the application cache

Related events:

  • checking: Fired when the browser looks for an update for the app cache
  • error: Triggered when an error occurs during checking for updates or downloading a resource
  • noupdate: Triggered when checking the description file and finding that the file has not changed
  • downloading: Triggered when the application cache resource starts to download
  • progress: Triggered continuously during the file download application cache
  • updateready: Triggered when the new application cache of the page is downloaded and can be used by swapCache()
  • cached: Fired when the app cache is fully available

Typically, these events are fired in the order described above as the page loads. The above events can also be triggered manually by calling the update() method.

data storage

HTTP cookies, often simply called cookies, are used on the client side to store session information. The standard requires servers to send the Set-Cookie HTTP header as part of the response with any HTTP request, which contains session information. Example of server response headers:

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

The browser then Set-Cookie session information, and then adds the Cookie HTTP header to each request to send the information back to the server, as follows:

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

The extra information sent back to the server can be used to uniquely verify which request the client came from.

A complete cookie includes:

  • Name: A name that uniquely identifies the cookie. Must be URL encoded.
  • Value: String value stored in the cookie. Must be URL encoded.
  • Domain: For which domain the cookie is valid.
  • path: For that path in the specified domain, the cookie should be sent to the server.
  • Expiration Time: A timestamp indicating when the cookie should be deleted.
  • Security flag: When specified, the cookie will only be sent to the server when using an SSL connection.
Set-Cookie:name=value; domain=www.laixiangran.cn; path=/; expires=Mon, 29 Oct 2018 03:53:10 GMT; secure;

Basic usage

Manipulating cookies in JavaScript is a bit complicated because the document.cookie property behaves differently in different usages.

When used to get attribute values, document.cookie returns all cookie strings available on the current page, a series of key-value pairs separated by semicolons, as follows:

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

When used to set a value, the document.cookie property will set a new cookie string to add to the existing cookie set, and will not overwrite the value of the original cookie like a normal object set property, unless the name of the set cookie is already exists, as follows:

// 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;

From the above code, we can see that it is not very intuitive and convenient for us to read, modify or delete the value of the specified cookie, so we can encapsulate some methods to facilitate our operation of the 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);
    }

};

Instructions:

// 设置 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());

size limit

  • The total number of cookies for each domain is limited, and it varies between different browsers. Below IE6 is a maximum of 20, IE7 and above is a maximum of 50, Firefox has a maximum of 50, Opera has a maximum of 30, and Safari and Chrome have no limit.
  • The size of the cookie is also limited, most browsers have about 4096B.

Web Storage

The purpose of Web Storage is to overcome some of the limitations imposed by cookies, without having to continuously send data back to the server when data needs to be strictly controlled on the client. The two main goals of Web Storage are:

  • Provides a way to store session data outside of cookies.
  • Provides a mechanism for storing large amounts of data that can exist across sessions.

Web Storage mainly defines two kinds of objects: sessionStorage and localStorage, which are instances of Storage objects. The differences between these two objects are as follows:

  • sessionStorage: Stores data specific to a session, that is, the data is only kept until the browser is closed. Most of the storage data size is limited to 2.5M, and a few browsers are limited to 5M or not limited.
  • localStorage: Data is saved to delete via JavaScript or the user clears the browser cache. Most of the storage data size is limited to 5M, and a few browsers are limited to 2.5M or not limited.

The Storage type has the following methods:

  • clear(): removes all values.
  • getItem(name): Get the corresponding value according to the specified name.
  • key(index): Get the name of the value at the index position.
  • removeItem(name): removes the key-value pair specified by name.
  • setItem(name, value): Set a corresponding value for the specified name, which is a string.

Operations on sessionStorage and localStorage will trigger the storage event , which has the following properties:

  • domain: The domain name of the storage space that has changed.
  • key: The key name to set or delete.
  • newValue: The new value if it is a set value, or null if it is a delete key.
  • oldValue: The value of the key before it was changed.

IndexedDB

The Indexed Database API, or IndexedDB for short, is a database that stores structured data in the browser. The idea is to create an API for saving and reading JavaScript objects, while also supporting querying and searching.

IndexedDB is designed to operate entirely asynchronously. Therefore, most operations are performed on request.

Basic usage

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

limit

  • Similar to Web Storage, it can only be operated by pages of the same origin (same protocol, domain name and port), so information cannot be shared across domains.
  • The maximum size of Firefox is 50M, and the maximum size of Firefox on the mobile terminal is 5M, and local file access is not allowed.
  • Chrome has a maximum size of 5M, allowing local file access.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325164174&siteId=291194637