使用ASP.NET MVC构建HTML5离线web应用程序

web应用程序的主要制约之一就是连接性。在HTML5到来之前我们就曾想挖掘浏览器的能力,以使web应用程序能像桌面应用程序一样功能强大和易 于使用,但浏览器始终让我们感到失望。虽然之前已出现了一些浏览器缓存技术,但这些缓存技术的设计初衷并不是为了使web应用程序能够完全地离线运行,令 人遗憾的是,事实上使用这些技术的web应用程序很容易出问题,而且难于使用。HTML5试图通过离线应用程序缓存( offline application cache)技术来填补浏览器的能力空缺,该技术能更加可靠地使web应用程序离线工作。

为什么web应用程序需要离线运行呢?

老实讲,一般来说,桌面电脑的web应用程序即使能够完全离线运行也不能带来多大的好处,因为桌面电脑一般都是一直连线的。我特别期待看到的是,移动设备web应用程序能够从离线应用程序缓存技术得到多大的好处。
在许多地方,移动电话普及率都在持续增长。如果能够自然地填补网络断线的鸿沟,移动设备浏览器中的web应用程序对用户来说就更加友好了。
在一些特定场景中,使整个应用程序能够离线运行,意味着我们只需创建一个跨平台的浏览器解决方案,而不必创建多个内建应用程序。
试想一下,一位销售员需要随时随地向她的顾客展示商品目录单。她可以使用任何她想要的电子设备,她首次浏览商品目录单时需要连线,之后便能够随时随地离线浏览。
应 用程序缓存技术并不只是在离线状态下才有用武之地。我们可以将应用程序缓存作为一个超级缓存,用于本地存储资源,这样可以加速应用程序启动。服务器上更新 了的资源可以在后台线程重新加载,加载完成之后便替换掉本地旧的资源并更新到正在运行的应用程序上。这种方式非常适用于桌面电脑的重量级web应用程序。

清单文件

要使用应用程序缓存,你不需要编写大量代码。你可以在一个简单的文本文件中定义需要离线使用的资源,这个文件被称作清单(manifest)文件。

清单文件格式

一个简单的清单文件具有如下格式:

双击代码全选

1

2

3

4

5

6

7

8

9

10

CACHE MANIFEST

# Version 1.0

CACHE:

/home/index

/content/style.css

/scripts/main.js

NETWORK:

/service/status

FALLBACK:

/logo.png /logo_offline.png

 

双击代码全选

1

 

 

其中,你必须将CACHE MANIFEST 头放在清单文件的第一行。
以数字符号#开头的行是注释行。这通常用于显式地修改清单文件以通知浏览器更新缓存。比如,在你更新了一张图片但没有修改图片的名称时,这种方式非常有用,因为浏览器并没有其他方式可以检测到服务器上的图片已被更新。
接 下来,清单文件包含了以下三节:CACHE,NETWORK以及FALLBACK。在CACHE节你可以指定需要缓存的资源。需要一直从服务器下载的资源 (即使在断线的情况下)则在NETWORK中指定。如果有大量的资源需要一直从服务器下载,你可以在NETWORK节中使用通配字符(即一个星号*)表 示。在FALLBACK节中,你可以指定在离线状态下可以使用的备用资源。
清单文件的格式并不特别严格。以上介绍的几个部分可以是任意次序的,它们甚至可以在一个清单文件中多次使用。
在清单文件中你可以使用相对路径或者绝对路径来定位资源。如果你使用相对路径,则必须以清单文件的位置作为参考来定位资源。

引用清单文件

要 将清单文件绑定到应用程序,需要将manifest属性添加到html标签上。每个引用清单文件的页面自身默认会被缓存。然而,还是建议在清单文件中显示 列出你想要缓存的资源。如果某个页面没有在清单文件中被指定,同时也不曾被在线浏览过,则在离线状态下无法访问到这个页面,因为浏览器无法知道页面是否存 在于本地缓存中。

双击代码全选

1

<html manifest="cache.manifest")/>

 

双击代码全选

1

 

 

检查缓存状态

使用应用程序缓存API,我们可以检查应用程序缓存的状态。使用window.applicationCache这个属性可以查询当前缓存的状态。该状态属性的值是一个介于0至5之间的数字,每个数字对应一个特定的缓存状态。

双击代码全选

1

 

 

缓存替换

当新缓存下载完成之后,它并不会立即替换掉旧的缓存,而是直到我们通知应用程序使用新缓存时它才进行替换。我们可以通过处理updateready事件,使用swapCache将旧缓存替换为新缓存。更新的资源要在刷新页面后才能见到。

双击代码全选

1

2

3

window.applicationCache.onupdateready = function(){

      window.applicationCache.swapCache();

});

 

怎样让用户知道你的应用程序可以离线运行呢?

据我所知,没有哪种浏览器会通知用户当前应用程序是能离线运行的。不过,我们可以自己通知用户:通过监听应用程序缓存的特定事件,当应用程序已经可以离线工作时通知用户。我们甚至可以将应用程序缓存生命周期的每个阶段都通知用户。
应 用程序缓存相关事件的处理是直截了当的。其中一个特别有用的事件是progress事件。每当一个资源下载完毕时这个事件被触发,其包含三个非常有用的属 性,我们可以用这三个属性来显示下载进度:lengthComputable、loaded以及total。首先,我们需检查 lengthComputable属性来判断loaded和total属性是否可用,接着我们使用loaded和total属性计算出资源下载的百分比进 度。

双击代码全选

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

window.applicationCache.onchecking = function (e) {

    updateCacheStatus('Checking for a new version of the application.');

};

window.applicationCache.ondownloading = function (e) {

    updateCacheStatus('Downloading a new offline version of the application');

};

window.applicationCache.oncached = function (e) {

    updateCacheStatus('The application is available offline.');

};

window.applicationCache.onerror = function (e) {

    updateCacheStatus('Something went wrong while updating the offline version of the application. It will not be available offline.');

};

window.applicationCache.onupdateready = function (e) {

    window.applicationCache.swapCache();

    updateCacheStatus('The application was updated. Refresh for the changes to take place.');

};

window.applicationCache.onnoupdate = function (e) {

    updateCacheStatus('The application is also available offline.');

};

window.applicationCache.onobsolete = function (e) {

    updateCacheStatus('The application cannot be updated, no manifest file was found.');

};

window.applicationCache.onprogress = function (e) {

    var message = 'Downloading offline resources.. ';

    if (e.lengthComputable) {

        updateCacheStatus(message + Math.round(e.loaded / e.total * 100) + '%');

    } else {

        updateCacheStatus(message);

    };

};

 

双击代码全选

1

 

 

怎样检测浏览器是处于在线状态还是离线状态呢?

你 需要知道浏览器是在线的还是离线的有以下几个原因:也许是因为你想通知用户其正在离线工作,也许是因为你想在网络断开时禁用应用程序的某些功能,还或许是 因为你想通过本地存储(local storage)技术以支持离线用户输入,然后在上线时将用户输入的文本同步到服务器。要实现这些需求,你可以通过自造基础架构,也可以通过使用开源项目 或第三方项目。

检测在线状态

从原理上讲检测在线状态应该是非常简单的,比如在标准状况下,你使用navigator单件的onLine属性就可以检测出当前浏览器是否在线。

双击代码全选

1

console.log(navigator.onLine)

 

但 事实上并非如此简单,因为各种浏览器对在线和离线的定义不尽相同。比如,旧版本的火狐浏览器只当用户显示地进行在线和离线状态切换时才更新onLine属 性的值,而忽略了实际的网络状况。抛开实现上的不一致,检测网络连接状况本身就不是一件微不足道的事情。比如,假设你的电脑是连接上了的,但是你的路由器 出问题了,这时应该显示什么状态呢?
一种流行的hack方法是检查每个AJAX请求的状态码,然后当状态码为不成功时则回退到离线机制。

事件处理

如果你想在浏览器改变连线状态时做一些事情,你可以通过处理offline和online事件来实现。但是请注意,和检查onLine属性一样,使用这两个事件也有类似问题。

双击代码全选

1

2

3

4

5

6

window.addEventListener('offline', function(e) {

  console.log('offline');

}, false);

window.addEventListener('online', function(e) {

  alert('online');

}, false);

 

双击代码全选

1

 

 

浏览器支持

除了Internet Explorer,所有主流现代浏览器都支持离线web应用程序。Internet Explorer 10也实现了相关规范,只是目前它还未发布。在caniuse.com上可以查看到每种浏览器及其版本对这一规范的支持情况。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

Grow your business fast with

Suku