澳门在线威尼斯官方 > 威尼斯澳门在线 > Web应用中的离线数据存储

原标题:Web应用中的离线数据存储

浏览次数:124 时间:2019-10-22

总结

能够望见,在Web应用中接收离线数据并不是十二分复杂。希望因而阅读那篇文章,各位可以在Web应用中参预离线数据的意义,使得你们的行使越发自个儿易用。你能够在这里下载全数的源码,尝试一下,大概修改,或然用在你们的施用中。

赞 收藏 评论

示例

在这里个事例中,我们用一个音乐专辑应用作为示范。可是本身并不计划在这里地原原本本展示整个应用,而是把关系IndexedDB的蒸蒸日上对挑出来解释。若是我们对这几个Web应用感兴趣的话,小说的后边也提供了源代码的下载。首先,让我们来开荒数据库并创设store:

JavaScript

// check if the indexedDB is supported if (!window.indexedDB) { throw 'IndexedDB is not supported!'; // of course replace that with some user-friendly notification } // variable which will hold the database connection var db; // open the database // first argument is database's name, second is it's version (I will talk about versions in a while) var request = indexedDB.open('album', 1); request.onerror = function (e) { console.log(e); }; // this will fire when the version of the database changes request.onupgradeneeded = function (e) { // e.target.result holds the connection to database db = e.target.result; // create a store to hold the data // first argument is the store's name, second is for options // here we specify the field that will serve as the key and also enable the automatic generation of keys with autoIncrement var objectStore = db.createObjectStore('cds', { keyPath: 'id', autoIncrement: true }); // create an index to search cds by title // first argument is the index's name, second is the field in the value // in the last argument we specify other options, here we only state that the index is unique, because there can be only one album with specific title objectStore.createIndex('title', 'title', { unique: true }); // create an index to search cds by band // this one is not unique, since one band can have several albums objectStore.createIndex('band', 'band', { unique: false }); };

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// check if the indexedDB is supported
if (!window.indexedDB) {
    throw 'IndexedDB is not supported!'; // of course replace that with some user-friendly notification
}
 
// variable which will hold the database connection
var db;
 
// open the database
// first argument is database's name, second is it's version (I will talk about versions in a while)
var request = indexedDB.open('album', 1);
 
request.onerror = function (e) {
    console.log(e);
};
 
// this will fire when the version of the database changes
request.onupgradeneeded = function (e) {
    // e.target.result holds the connection to database
    db = e.target.result;
 
    // create a store to hold the data
    // first argument is the store's name, second is for options
    // here we specify the field that will serve as the key and also enable the automatic generation of keys with autoIncrement
    var objectStore = db.createObjectStore('cds', { keyPath: 'id', autoIncrement: true });
 
    // create an index to search cds by title
    // first argument is the index's name, second is the field in the value
    // in the last argument we specify other options, here we only state that the index is unique, because there can be only one album with specific title
    objectStore.createIndex('title', 'title', { unique: true });
 
    // create an index to search cds by band
    // this one is not unique, since one band can have several albums
    objectStore.createIndex('band', 'band', { unique: false });
};

相信上面包车型地铁代码还是优秀简单明了的。估摸你也只顾到上述代码中展开数据库时会传入一个版本号,还用到了onupgradeneeded事件。当你以较新的本子展开数据库时就能触发那几个事件。假如相应版本的数据库尚荒诞不经,则会触发事件,随后大家就能创造所需的store。接下来我们还创建了七个目录,贰个用于标题找寻,二个用来乐队搜索。今后让大家再来看看怎么着增删专辑:

JavaScript

// adding $('#add-album').on('click', function () { // create the transaction // first argument is a list of stores that will be used, second specifies the flag // since we want to add something we need write access, so we use readwrite flag var transaction = db.transaction([ 'cds' ], 'readwrite'); transaction.onerror = function (e) { console.log(e); }; var value = { ... }; // read from DOM // add the album to the store var request = transaction.objectStore('cds').add(value); request.onsuccess = function (e) { // add the album to the UI, e.target.result is a key of the item that was added }; }); // removing $('.remove-album').on('click', function () { var transaction = db.transaction([ 'cds' ], 'readwrite'); var request = transaction.objectStore('cds').delete(/* some id got from DOM, converted to integer */); request.onsuccess = function () { // remove the album from UI } });

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// adding
$('#add-album').on('click', function () {
    // create the transaction
    // first argument is a list of stores that will be used, second specifies the flag
    // since we want to add something we need write access, so we use readwrite flag
    var transaction = db.transaction([ 'cds' ], 'readwrite');
    transaction.onerror = function (e) {
        console.log(e);
    };
    var value = { ... }; // read from DOM
    // add the album to the store
    var request = transaction.objectStore('cds').add(value);
    request.onsuccess = function (e) {
        // add the album to the UI, e.target.result is a key of the item that was added
    };
});
 
// removing
$('.remove-album').on('click', function () {
    var transaction = db.transaction([ 'cds' ], 'readwrite');
    var request = transaction.objectStore('cds').delete(/* some id got from DOM, converted to integer */);
    request.onsuccess = function () {
        // remove the album from UI
    }
});

是还是不是看起来直接明了?这里对数据库全体的操作都基于事务的,只有如此本事保险数据的大器晚成致性。未来最后要做的正是显示音乐专辑:

JavaScript

request.onsuccess = function (e) { if (!db) db = e.target.result; var transaction = db.transaction([ 'cds' ]); // no flag since we are only reading var store = transaction.objectStore('cds'); // open a cursor, which will get all the items from database store.openCursor().onsuccess = function (e) { var cursor = e.target.result; if (cursor) { var value = cursor.value; $('#albums-list tbody').append(' '+ value.title +''+ value.band +''+ value.genre +''+ value.year +'

1
2
3
4
5
6
7
8
9
10
11
12
request.onsuccess = function (e) {
    if (!db) db = e.target.result;
 
    var transaction = db.transaction([ 'cds' ]); // no flag since we are only reading
    var store = transaction.objectStore('cds');
    // open a cursor, which will get all the items from database
    store.openCursor().onsuccess = function (e) {
        var cursor = e.target.result;
        if (cursor) {
            var value = cursor.value;
            $('#albums-list tbody').append('
'+ value.title +''+ value.band +''+ value.genre +''+ value.year +'

‘); // move to the next item in the cursor cursor.continue(); } }; }

那亦不是十三分复杂。能够望见,通过应用IndexedDB,能够十分轻便的保存复杂对象,也能够因而索引来寻觅想要的内容:

JavaScript

function getAlbumByBand(band) { var transaction = db.transaction([ 'cds' ]); var store = transaction.objectStore('cds'); var index = store.index('band'); // open a cursor to get only albums with specified band // notice the argument passed to openCursor() index.openCursor(IDBKeyRange.only(band)).onsuccess = function (e) { var cursor = e.target.result; if (cursor) { // render the album // move to the next item in the cursor cursor.continue(); } }); }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function getAlbumByBand(band) {
    var transaction = db.transaction([ 'cds' ]);
    var store = transaction.objectStore('cds');
    var index = store.index('band');
    // open a cursor to get only albums with specified band
    // notice the argument passed to openCursor()
    index.openCursor(IDBKeyRange.only(band)).onsuccess = function (e) {
        var cursor = e.target.result;
        if (cursor) {
            // render the album
            // move to the next item in the cursor
            cursor.continue();
        }
    });
}

动用索引的时候和动用store同样,也能透过游标(cursor)来遍历。由于同三个索引值名下恐怕有几许条数据(要是索引不是unique的话),所以这里大家要求利用IDBKeyRange。它能依照钦命的函数对结果集进行过滤。这里,大家只想依据钦命的乐队实行查找,所以我们用到了only()函数。也能应用其他类似于lowerBound()upperBound()bound()等函数,它们的效劳也是不在话下的。

示例

第生机盎然,你须要在页面上钦点AppCache的配置文件:

XHTML

<!DOCTYPE html> <html manifest="manifest.appcache"> ... </html>

1
2
3
4
<!DOCTYPE html>
<html manifest="manifest.appcache">
...
</html>

在这里处相对记得在服务器端公布上述配置文件的时候,须求将MIME类型设置为text/cache-manifest,不然浏览器不能符合规律解析。

接下去是创制以前定义好的各样能源。大家假如在这里个示例中,你付出的是一个相互类站点,顾客能够在上边联系旁人而且宣布批评。客户在离线的地方下依然得以访谈网址的静态部分,而联系以至发布批评的页面则会被别的页面替代,不可能访谈。

好的,大家这就出手定义那么些静态财富:

JavaScript

CACHE MANIFEST CACHE: /about.html /portfolio.html /portfolio_gallery/image_1.jpg /portfolio_gallery/image_2.jpg /info.html /style.css /main.js /jquery.min.js

1
2
3
4
5
6
7
8
9
10
11
CACHE MANIFEST
 
CACHE:
/about.html
/portfolio.html
/portfolio_gallery/image_1.jpg
/portfolio_gallery/image_2.jpg
/info.html
/style.css
/main.js
/jquery.min.js

旁注:配置文件写起来有某个十分不便于。比释迦牟尼佛讲,假令你想缓存整个目录,你不能够一向在CACHE部分行使通配符(*),而是只可以在NETWO本田CR-VK部分应用通配符把装有不应该被缓存的能源写出来。

您无需显式地缓存包括配置文件的页面,因为那几个页面会自动被缓存。接下来大家为调换和商酌的页面定义FALLBACK部分:

JavaScript

FALLBACK: /contact.html /offline.html /comments.html /offline.html

1
2
3
FALLBACK:
/contact.html /offline.html
/comments.html /offline.html

最终大家用一个通配符来阻止别的的财富被缓存:

威尼斯澳门在线 ,JavaScript

NETWORK: *

1
2
NETWORK:
*

提及底的结果便是上面那样:

JavaScript

CACHE MANIFEST CACHE: /about.html /portfolio.html /portfolio_gallery/image_1.jpg /portfolio_gallery/image_2.jpg /info.html /style.css /main.js /jquery.min.js FALLBACK: /contact.html /offline.html /comments.html /offline.html NETWORK: *

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
CACHE MANIFEST
 
CACHE:
/about.html
/portfolio.html
/portfolio_gallery/image_1.jpg
/portfolio_gallery/image_2.jpg
/info.html
/style.css
/main.js
/jquery.min.js
 
FALLBACK:
/contact.html /offline.html
/comments.html /offline.html
 
NETWORK:
*

还也有生龙活虎件很注重的事情要记得:你的财富只会被缓存一遍!也正是说,假使财富创新了,它们不会自动更新,除非你改改了安排文件。所以有三个一级施行是,在铺排文件中扩展如日方升项版本号,每趟换代财富的时候顺便更新版本号:

JavaScript

CACHE MANIFEST # version 1 CACHE: ...

1
2
3
4
5
6
CACHE MANIFEST
 
# version 1
 
CACHE:
...

引言

搭飞机HTML5的惠临,各样Web离线数据技艺步向了开荒职员的视界。诸如AppCache、localStorage、sessionStorage和IndexedDB等等,每风流洒脱种本领都有它们分别适用的范围。举例AppCache就比较符合用来离线起动应用,只怕在离线状态下使应用的方兴未艾有的机能照常运作。接下来小编将会为我们作详细介绍,并且用一些代码片段来展现如何使用那个技能。

IndexedDB

在本身个人看来,这是最风趣的风姿浪漫种技艺。它能够保留多量透过索引(indexed)的数额在浏览器端。那样一来,就能够在顾客端保存复杂对象,大文书档案等等数据。何况客户可以在离线处境下访问它们。这黄金年代特色大致适用于具备体系的Web应用:倘让你写的是邮件客商端,你可以缓存顾客的邮件,以供稍后再看;假若你写的是相册类应用,你能够离线保存客商的相片;倘诺您写的是GPS导航,你能够缓存客商的门径……数不尽。

IndexedDB是贰个面向对象的数据库。那就意味着在IndexedDB中既荒诞不经表的概念,也不曾SQL,数据是以键值对的款型保留的。此中的键不只能够是字符串和数字等基础项目,也能够是日期和数组等繁缛类型。那个数据库本人营造于积存(store,三个store类似于关系型数据中表的定义)的根基上。数据库中每个值都不能够不要有相应的键。每一个键不只能够自动生成,也得以在插入值的时候钦点,也足以取自于值中的有个别字段。借让你决定使用值中的字段,那么只好向里面增加Javascript对象,因为基础数据类型不像Javascript对象那样有自定义属性。

AppCache

假如你的Web应用中有部分效应(大概全部应用)需求在抽离服务器的景观下行使,那么就足以因而AppCache来让您的顾客在离线状态下也能使用。你所要求做的就是创设贰个布署文件,在中间钦命哪些能源必要被缓存,哪些无需。别的,仍是能够在里头钦定有个别联机财富在脱机条件下的代表财富。

AppCache的安插文件平时是三个以.appcache末段的文书文件(推荐写法)。文件以CACHE MANIFEST早先,包涵下列三部分剧情:

  • CACHE – 钦命了什么样财富在客商率先次访谈站点的时候必要被下载并缓存
  • NETWORK – 钦定了什么财富须求在如火如荼道条件下本事访谈,这几个能源从不被缓存
  • FALLBACK – 钦命了上述财富在脱机条件下的替代财富

Web应用中的离线数据存储

2014/02/15 · HTML5, JavaScript · HTML5, Javascript

本文由 伯乐在线 - njuyz 翻译。未经许可,禁止转发!
丹麦语出处:Nettuts+。应接到场翻译组。

为了升高Web应用的顾客体验,想必很多开辟者都会项目中引进离线数据存款和储蓄机制。可是面对五花八门的离线数据本事,哪大器晚成种才是最能满足项目须求的吧?本文将帮衬各位找到最合适的那一个。

关于小编:njuyz

威尼斯澳门在线 1

(腾讯网网易:@njuyz) 个人主页 · 笔者的稿子 · 11

威尼斯澳门在线 2

LocalStorage和SessionStorage

借使您想在Javascript代码里面保存些数据,那么那多个东西就派上用场了。前贰个得以保留数据,恒久不会晚点(expire)。只假如如出生龙活虎辙的域和端口,全部的页面中都能访谈到通过LocalStorage保存的多寡。举个简单的事例,你能够用它来保存顾客设置,客户能够把她的私人民居房爱好保存在那时此刻选用的管理器上,现在张开应用的时候能够一直加载。前者也能保存数据,可是倘使关闭浏览器窗口(译者注:浏览器窗口,window,如若是多tab浏览器,则此处指代tab)就失效了。何况这个多少不能够在分化的浏览器窗口之间分享,即便是在分化的窗口中做客同一个Web应用的别样页面。

旁注:有几许索要提醒的是,LocalStorage和SessionStorage里面只能保留基本类型的多少,也正是字符串和数字类型。另外具备的多寡足以经过各自的toString()方法转变后保存。假设您想保留四个目的,则须求选取JSON.stringfy方法。(假诺这么些目的是多少个类,你能够复写它暗许的toString()方法,这一个方法会自动被调用)。

示例

我们不妨来拜候在此之前的例子。在联系人和争辩的一些,大家得以每日保存客商输入的事物。那样一来,纵然客户十分的大心关闭了浏览器,以前输入的东西也不会丢弃。对于jQuery来讲,那一个功能是小菜大器晚成碟。(注意:表单中逐个输入字段都有id,在此大家就用id来代表具体的字段)

JavaScript

$('#comments-input, .contact-field').on('keyup', function () { // let's check if localStorage is supported if (window.localStorage) { localStorage.setItem($(this).attr('id'), $(this).val()); } });

1
2
3
4
5
6
$('#comments-input, .contact-field').on('keyup', function () {
   // let's check if localStorage is supported
   if (window.localStorage) {
      localStorage.setItem($(this).attr('id'), $(this).val());
   }
});

每回提交联系人和评价的表单,我们要求清空缓存的值,我们得以如此管理提交(submit)事件:

JavaScript

$('#comments-form, #contact-form').on('submit', function () { // get all of the fields we saved $('#comments-input, .contact-field').each(function () { // get field's id and remove it from local storage localStorage.removeItem($(this).attr('id')); }); });

1
2
3
4
5
6
7
$('#comments-form, #contact-form').on('submit', function () {
   // get all of the fields we saved
   $('#comments-input, .contact-field').each(function () {
      // get field's id and remove it from local storage
      localStorage.removeItem($(this).attr('id'));
   });
});

末段,每一趟加载页面包车型地铁时候,把缓存的值填充到表单上就可以:

JavaScript

// get all of the fields we saved $('#comments-input, .contact-field').each(function () { // get field's id and get it's value from local storage var val = localStorage.getItem($(this).attr('id')); // if the value exists, set it if (val) { $(this).val(val); } });

1
2
3
4
5
6
7
8
9
// get all of the fields we saved
$('#comments-input, .contact-field').each(function () {
   // get field's id and get it's value from local storage
   var val = localStorage.getItem($(this).attr('id'));
   // if the value exists, set it
   if (val) {
      $(this).val(val);
   }
});

本文由澳门在线威尼斯官方发布于威尼斯澳门在线,转载请注明出处:Web应用中的离线数据存储

关键词:

上一篇:反而商业成了不能超出的边境线

下一篇:没有了