我有一个使用应用程序缓存的离线Web应用程序。 我需要提供约10MB-20MB的数据以保存(客户端),主要由PNG图像文件组成。 操作如下:
- Web应用程序下载并安装在应用程序缓存中(使用清单)
- Web应用程序从服务器请求PNG数据文件(如何?-见下面的替代方案)
- 偶尔Web应用程序与服务器进行重新同步,并对PNG数据库进行小的部分更新/删除/添加
- FYI:服务器是JSON REST服务器,可以将文件放置在wwwroot以便取用
请参见下方更新
AppCache(通过清单添加所有PNG文件,然后按需更新)
- CON:PNG数据库项的任何更改都意味着完全下载清单中的所有项目(非常糟糕!)
WebStorage
- CON:设计用于JSON存储
- CON:仅能通过base64编码存储blob(可能是致命缺陷,因为解码成本很高)
- CON:webStorage的硬限制为5MB http://htmlui.com/blog/2011-08-23-5-obscure-facts-about-html5-localstorage.html
PhoneGap和SQLLite
- CON:赞助商将拒绝它作为需要认证的本机应用程序
ZIP文件
- 服务器创建zip文件,将其放置在wwwroot中,并通知客户端
- 用户必须手动解压缩(至少我是这样看的),并保存到客户端文件系统
- Web应用程序使用FileSystem API引用文件
- CON:ZIP可能太大(zip64?),创建时间长
- CON:不确定FileSystem API是否总是可以从沙箱中读取(我认为是)
USB或SD卡(回到石器时代...)
- 用户将在离线前位于服务器位置
- 因此,我们可以让他插入SD卡,让服务器填充PNG文件
- 然后用户将其插入笔记本电脑、平板电脑
- Web应用程序将使用FileSystem API读取文件
- CON:不确定FileSystem API是否总是可以从沙箱中读取(我认为是)
WebSQL
- CON: W3C已经放弃了它(相当不好)
- 我可能会考虑一个JavaScript包装器,它使用IndexedDB和WebSQL作为备用方案
FileSystem API
- Chrome支持Blob的读/写操作
- CON:IE和FireFox不清楚(IE10具有非标准的msSave)
- caniuse.com报告IOS和Android支持(但这只是JSON的r/w,还是包括完整的Blob API用于写入?
- CON:FireFox成员不喜欢FileSystem API,并且不清楚他们是否支持保存Blobs:https://hacks.mozilla.org/2012/07/why-no-filesystem-api-in-firefox/
- PRO:根据jsperf来看,与IndexedDB相比,对于Blobs速度要快得多:http://jsperf.com/indexeddb-vs-localstorage/15(第2页)
IndexedDB
- 在IE10、FireFox中有良好的支持(保存、读取Blobs)
- 速度快,管理比文件系统更容易(删除、更新)
- PRO:参见速度测试:http://jsperf.com/indexeddb-vs-localstorage/15
- 请参阅此文章,了解在IndexedDB中存储和显示图像:https://hacks.mozilla.org/2012/02/storing-images-and-files-in-indexeddb/
- CON:我确认Chrome目前不支持Blob写入(当前的bug,但不清楚何时修复)
- UPDATE:2014年6月的博客文章表明Chrome现在支持在
IndexedDB
中使用blobs - UPDATE:这个caniuse/indexeddb证实:“Chrome 36及以下版本不支持将Blob对象作为indexedDB值。”;这意味着Chrome36及以上版本支持Blob对象。
LawnChair JavaScript包装器:http://brian.io/lawnchair/
- 优点:非常干净的 IndexedDB、WebSQL 或任何数据库的封装(类似 polyfill)。
- 缺点:无法存储二进制 blob,只能存储数据:URI(base64 编码),可能由于解码成本而导致致命缺陷。
IndexedDB JQUERY polyFill https://github.com/axemclion/jquery-indexeddb
- Parashuram 写了一个很好的 JQUERY 包装器,用于原始 IndexedDB 接口。
- 优点:大大简化了使用 IndexedDB,我希望为 Chrome FileSystemAPI 添加一个 shim/polyfill。
- 缺点:它应该处理 blob,但我无法让它工作。
idb.filesystem.js http://ericbidelman.tumblr.com/post/21649963613/idb-filesystem-js-bringing-the-html5-filesystem-api
- Google 的 Eric Bidelman 编写了一个经过充分测试的 PolyFill FileSystem API,它使用 Indexed DB 作为后备。
- 优点:FileSystem API 很适合存储 blob。
- 优点:在 FireFox 和 Chrome 上运行得很好。
- 优点:非常适合与基于云的 CouchDB 同步。
- 缺点:不清楚为什么,但它在 IE10 上不能正常工作。
PouchDB JavaScript Library http://pouchdb.com/
- 用于将 CouchDB 与本地数据库同步(使用 WebSQL 或 IndexedDB,不是我的问题)。
- 缺点:没有缺点,PouchDB 现在支持所有近期浏览器(IE、Chrome、Firefox、移动版 Chrome 等)以及许多旧浏览器的二进制 blob。当我第一次写这篇文章时,情况并非如此。
注意:要查看我创建的 PNG 的 data:uri 编码示例,请转到:http://jsbin.com/ivefak/1/edit
期望的/有用的/不需要的功能
- 客户端没有本地应用程序(如EXE,PhoneGap,ObjectiveC等),仅为纯Web应用程序
- 只需要在最新的Chrome,FireFox和IE10上运行笔记本电脑
- 强烈希望Android平板电脑使用相同的解决方案(IOS也可以),但只需要一个浏览器即可工作(FF,Chrome等)
- 快速进行初始数据库填充
- 要求:Web应用程序从存储(数据库,文件)中非常快速地检索图像
- 不适合消费者。我们可以限制浏览器,并要求用户执行特殊设置和任务,但让我们尽量减少这些操作
IndexedDB实现
- 有一篇关于IE,Firefox和Chrome如何内部实现此功能的优秀文章:http://www.aaron-powell.com/web/indexeddb-storage
- 简而言之:
- IE使用与Exchange和Active Directory相同的数据库格式来实现IndexedDB
- Firefox正在使用SQLite,因此将NoSQL数据库实现到SQL数据库中
- Chrome(和WebKit)正在使用源于BigTable的键/值存储
我的当前结果
- 我选择使用IndexedDB方法(并使用FileSystemAPI在Chrome上进行polyfill,直到它们支持blob支持)
- 对于获取瓷砖,我遇到了一个困境,因为JQUERY的人们正在抱怨将其添加到AJAX中
- 我选择了Phil Parsons的XHR2-Lib,它非常类似于JQUERY .ajax() https://github.com/p-m-p/xhr2-lib
- 100MB下载的性能(IE10 4s,Chrome 6s,FireFox 7s)。
- 我无法让任何IndexedDB包装器对blobs起作用(lawnchair,PouchDB,jquery-indexeddb等)
- 我自己编写了包装器,性能为(IE10 2s,Chrome 3s,FireFox 10s)
- 对于FF,我假设我们正在看到使用关系数据库(sqllite)存储非关系型数据时出现的性能问题
- 请注意,Chrome具有出色的调试工具(开发人员选项卡,资源),可用于检查IndexedDB的状态。
最终结果如下所示:
更新
PouchDB现在支持二进制blob以适用于所有最新的浏览器(IE,Chrome,Firefox,移动版Chrome等)以及许多旧版本的浏览器。当我第一次发布此帖子时,情况并非如此。