首頁 web前端 H5教程 使用ASP.NET MVC构建HTML5离线web应用程序

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

May 17, 2016 am 09:08 AM

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

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

       老实讲,一般来说,桌面电脑的web应用程序即使能够完全离线运行也不能带来多大的好处,因为桌面电脑一般都是一直连线的。我特别期待看到的是,移动设备web应用程序能够从离线应用程序缓存技术得到多大的好处。

       在许多地方,移动电话普及率都在持续增长。如果能够自然地填补网络断线的鸿沟,移动设备浏览器中的web应用程序对用户来说就更加友好了。

       在一些特定场景中,使整个应用程序能够离线运行,意味着我们只需创建一个跨平台的浏览器解决方案,而不必创建多个内建应用程序。

       试想一下,一位销售员需要随时随地向她的顾客展示商品目录单。她可以使用任何她想要的电子设备,她首次浏览商品目录单时需要连线,之后便能够随时随地离线浏览。

       应用程序缓存技术并不只是在离线状态下才有用武之地。我们可以将应用程序缓存作为一个超级缓存,用于本地存储资源,这样可以加速应用程序启动。服务器上更新了的资源可以在后台线程重新加载,加载完成之后便替换掉本地旧的资源并更新到正在运行的应用程序上。这种方式非常适用于桌面电脑的重量级web应用程序。

       清单文件

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

       清单文件格式

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

  1. CACHE MANIFEST
  2. # Version 1.0
  3. CACHE:
  4. /home/index
  5. /content/style.css
  6. /scripts/main.js
  7. NETWORK:
  8. /service/status
  9. FALLBACK:
  10. /logo.png /logo_offline.png
复制代码


       其中,你必须将CACHE MANIFEST 头放在清单文件的第一行。

       以数字符号#开头的行是注释行。这通常用于显式地修改清单文件以通知浏览器更新缓存。比如,在你更新了一张图片但没有修改图片的名称时,这种方式非常有用,因为浏览器并没有其他方式可以检测到服务器上的图片已被更新。

       接下来,清单文件包含了以下三节:CACHE,NETWORK以及FALLBACK。在CACHE节你可以指定需要缓存的资源。需要一直从服务器下载的资源(即使在断线的情况下)则在NETWORK中指定。如果有大量的资源需要一直从服务器下载,你可以在NETWORK节中使用通配字符(即一个星号*)表示。在FALLBACK节中,你可以指定在离线状态下可以使用的备用资源。

       清单文件的格式并不特别严格。以上介绍的几个部分可以是任意次序的,它们甚至可以在一个清单文件中多次使用。

       在清单文件中你可以使用相对路径或者绝对路径来定位资源。如果你使用相对路径,则必须以清单文件的位置作为参考来定位资源。

       引用清单文件

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

复制代码


       检查缓存状态

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

21.jpg


       你可以使用setInterval函数来快速显示状态变化。

  1. setInterval(function () {
  2.       console.log(window.applicationCache.status)
  3. }, 500);
复制代码


       事件处理

       除了检查缓存状态,我们还可以处理特定事件。

22.jpg


       缓存替换

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

  1. window.applicationCache.onupdateready = function(){
  2.       window.applicationCache.swapCache();
  3. });
复制代码


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

       据我所知,没有哪种浏览器会通知用户当前应用程序是能离线运行的。不过,我们可以自己通知用户:通过监听应用程序缓存的特定事件,当应用程序已经可以离线工作时通知用户。我们甚至可以将应用程序缓存生命周期的每个阶段都通知用户。

       应用程序缓存相关事件的处理是直截了当的。其中一个特别有用的事件是progress事件。每当一个资源下载完毕时这个事件被触发,其包含三个非常有用的属性,我们可以用这三个属性来显示下载进度:lengthComputable、loaded以及total。首先,我们需检查lengthComputable属性来判断loaded和total属性是否可用,接着我们使用loaded和total属性计算出资源下载的百分比进度。

  1. window.applicationCache.onchecking = function (e) {
  2.     updateCacheStatus('Checking for a new version of the application.');
  3. };
  4. window.applicationCache.ondownloading = function (e) {
  5.     updateCacheStatus('Downloading a new offline version of the application');
  6. };

  7. window.applicationCache.oncached = function (e) {
  8.     updateCacheStatus('The application is available offline.');
  9. };

  10. window.applicationCache.onerror = function (e) {
  11.     updateCacheStatus('Something went wrong while updating the offline version of the application. It will not be available offline.');
  12. };

  13. window.applicationCache.onupdateready = function (e) {
  14.     window.applicationCache.swapCache();
  15.     updateCacheStatus('The application was updated. Refresh for the changes to take place.');
  16. };

  17. window.applicationCache.onnoupdate = function (e) {
  18.     updateCacheStatus('The application is also available offline.');
  19. };

  20. window.applicationCache.onobsolete = function (e) {
  21.     updateCacheStatus('The application cannot be updated, no manifest file was found.');
  22. };

  23. window.applicationCache.onprogress = function (e) {
  24.     var message = 'Downloading offline resources.. ';
  25.     if (e.lengthComputable) {
  26.         updateCacheStatus(message + Math.round(e.loaded / e.total * 100) + '%');
  27.     } else {
  28.         updateCacheStatus(message);
  29.     };
  30. };
复制代码


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

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

       检测在线状态

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

  1. console.log(navigator.onLine)
复制代码


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

       一种流行的hack方法是检查每个AJAX请求的状态码,然后当状态码为不成功时则回退到离线机制。

       事件处理

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

  1. window.addEventListener('offline', function(e) {
  2.   console.log('offline');
  3. }, false);
  4. window.addEventListener('online', function(e) {
  5.   alert('online');
  6. }, false);
复制代码


       浏览器支持

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

       对于大部分实现,各主流浏览器基本上是相一致的。但在实现存储限额以及对限额的管理(这两项没有定义在规范中)上,各浏览器差异比较大。在测试你的web应用程序时应该考虑这个问题,移动设备中的浏览器在缓存大小上可是斤斤计较的。

       使用ASP.NET MVC生成和提供清单文件

       生成清单文件

       利用ASP.NET MVC创建和提供清单文件有几种方式。最简单地方式就是让ASP.NET MVC提供静态文本文件。然而,如果我们想要使用内建的ASP.NET MVC特性来解析路由,或者想编写代码来动态操控清单文件,我们最好使用自定义的action result。

       我把这个自定义的action result命名为ManifestResult,它继承自MVC框架中的FileResult类。提供清单文件服务时应该使用'text/cache-manifest' MIME类型,我把这个字符串传递给了父类的构造函数。

  1. public class ManifestResult : FileResult
  2. {
  3.     public ManifestResult(string version)
  4.         : base("text/cache-manifest") { }
  5. }
复制代码


       ManifestResult类具有四个属性,其中三个属性对应清单文件的三个节,另外一个属性对应版本号。表示CACHE节和NETWORK节的两个属性仅仅是字符串枚举,而表示FALLBACK节的属性是字典类型的,用于将资源映射到FALLBACK指定的资源。

  1. public class ManifestResult : FileResult
  2. {
  3.     public ManifestResult(string version)
  4.         : base("text/cache-manifest")
  5.     {
  6.             Version = version;
  7.         CacheResources = new List();
  8.         NetworkResources = new List();
  9.         FallbackResources = new Dictionary();
  10.     }
  11.     public string Version { get; set; }
  12.     public IEnumerable CacheResources { get; set; }
  13.     public IEnumerable NetworkResources { get; set; }
  14.     public Dictionary FallbackResources { get; set; }
  15. }
复制代码


       要将格式化的清单文件输出到响应流,需要重写WriteFile方法。

  1. protected override void WriteFile(HttpResponseBase response)
  2. {
  3. WriteManifestHeader(response);
  4.     WriteCacheResources(response);
  5.     WriteNetwork(response);
  6.     WriteFallback(response);
  7. }
  8. private void WriteManifestHeader(HttpResponseBase response)
  9. {
  10.     response.Output.WriteLine("CACHE MANIFEST");
  11.     response.Output.WriteLine("#V" + Version ?? string.Empty);
  12. }
  13. private void WriteCacheResources(HttpResponseBase response)
  14. {
  15.     response.Output.WriteLine("CACHE:");
  16.     foreach (var cacheResource in CacheResources)
  17.         response.Output.WriteLine(cacheResource);
  18. }
  19. private void WriteNetwork(HttpResponseBase response)
  20. {
  21.     response.Output.WriteLine();
  22.     response.Output.WriteLine("NETWORK:");
  23.     foreach (var networkResource in NetworkResources)
  24.         response.Output.WriteLine(networkResource);
  25. }
  26. private void WriteFallback(HttpResponseBase response)
  27. {
  28.     response.Output.WriteLine();
  29.     response.Output.WriteLine("FALLBACK:");
  30.     foreach (var fallbackResource in FallbackResources)
  31.         response.Output.WriteLine(fallbackResource.Key + " " + fallbackResource.Value);
  32. }
复制代码


       提供清单文件服务

       为了提供清单文件服务,我们要将相应的action添加到相应的控制器类中,以生成和返回清单文件的动作结果(action result)。在该action中,我们利用MVC的UrlHelper对象来正确地解析路由。

  1. public ActionResult Manifest()
  2. {
  3.      var manifestResult = new ManifestResult("1.0")
  4.     {
  5.          CacheResources = new List()
  6.              {
  7.                    Url.Action("Index", "Home"),
  8.                    "/content/style.css",
  9.                    "/scripts/main.js"
  10.              },
  11.              NetworkResources = new string[] { Url.Action("Status", "Service")},
  12.              FallbackResources = { { "/logo.png", "/logo_offline.png" } }
  13.     };
  14.     return manifestResult;
  15. }
复制代码


       为清单文件设置路由

       我们应该为清单文件设置特定的路由。大多数浏览器对清单文件的位置没有严格的规定,而最可靠的跨浏览器方式是将清单文件放在根目录,并将其命名为cache.manifest。在应用程序启动时,下面的代码将这个新的“cache.manifest”路由添加到路由表中。

  1. routes.MapRoute("cache.manifest", "cache.manifest", new { controller = "Resources", action = "Manifest" });
复制代码


       结论

       离线web应用程序是正处于不断发展中的HTML规范的重要内容之一。根据实际用例,你可能仅仅是利用这个特性来缓存资源或者让web应用程序完全离线运行。这个特性的中心就是清单文件。清单文件的格式和要求一点也不复杂,使用ASP.NET MVC或其他服务端技术可以直截了当地生成和提供清单文件服务。编写好清单文件之后,使用应用程序缓存API就可以很容易地进行缓存更新。你也可以使用这组API来查询缓存状态和处理应用程序缓存的特定事件。想知道浏览器处于在线状态还是离线状态,你可以通过检查navigator对象的onLine属性,或者处理特定的在线和离线事件来判断。


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

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

h5項目怎麼運行 h5項目怎麼運行 Apr 06, 2025 pm 12:21 PM

運行 H5 項目需要以下步驟:安裝 Web 服務器、Node.js、開發工具等必要工具。搭建開發環境,創建項目文件夾、初始化項目、編寫代碼。啟動開發服務器,使用命令行運行命令。在瀏覽器中預覽項目,輸入開發服務器 URL。發布項目,優化代碼、部署項目、設置 Web 服務器配置。

H5頁面製作究竟指什麼 H5頁面製作究竟指什麼 Apr 06, 2025 am 07:18 AM

H5 頁面製作是指使用 HTML5、CSS3 和 JavaScript 等技術,創建跨平台兼容的網頁。其核心在於瀏覽器解析代碼,渲染結構、樣式和交互功能。常見技術包括動畫效果、響應式設計和數據交互。為避免錯誤,應使用開發者工具調試;而性能優化和最佳實踐則包括圖像格式優化、減少請求和代碼規範等,以提高加載速度和代碼質量。

h5怎麼製作點擊圖標 h5怎麼製作點擊圖標 Apr 06, 2025 pm 12:15 PM

製作 H5 點擊圖標的步驟包括:在圖像編輯軟件中準備方形源圖像。在 H5 編輯器中添加交互性,設置點擊事件。創建覆蓋整個圖標的熱點。設置點擊事件的操作,如跳轉頁面或觸發動畫。導出 H5 文檔為 HTML、CSS 和 JavaScript 文件。將導出的文件部署到網站或其他平台。

什麼是H5編程語言? 什麼是H5編程語言? Apr 03, 2025 am 12:16 AM

H5不是獨立編程語言,而是HTML5、CSS3和JavaScript的集合,用於構建現代Web應用。 1.HTML5定義網頁結構和內容,提供新標籤和API。 2.CSS3控製樣式和佈局,引入動畫等新特性。 3.JavaScript實現動態交互,通過DOM操作和異步請求增強功能。

H5指的是什麼?探索上下文 H5指的是什麼?探索上下文 Apr 12, 2025 am 12:03 AM

H5referstoHTML5,apivotaltechnologyinwebdevelopment.1)HTML5introducesnewelementsandAPIsforrich,dynamicwebapplications.2)Itsupportsmultimediawithoutplugins,enhancinguserexperienceacrossdevices.3)SemanticelementsimprovecontentstructureandSEO.4)H5'srespo

H5頁面製作適合哪些應用場景 H5頁面製作適合哪些應用場景 Apr 05, 2025 pm 11:36 PM

H5(HTML5)適合應用於輕量級應用,如營銷活動頁面、產品展示頁面和企業宣傳微網站。它優勢在於跨平台性和豐富的交互性,但局限性在於復雜的交互和動畫、本地資源訪問和離線功能。

H5頁面製作是前端開發嗎 H5頁面製作是前端開發嗎 Apr 05, 2025 pm 11:42 PM

是的,H5頁面製作是前端開發的重要實現方式,涉及HTML、CSS和JavaScript等核心技術。開發者通過巧妙結合這些技術,例如使用<canvas>標籤繪製圖形或使用JavaScript控制交互行為,構建出動態且功能強大的H5頁面。

h5怎麼製作彈窗 h5怎麼製作彈窗 Apr 06, 2025 pm 12:12 PM

H5 彈窗製作步驟:1. 確定觸發方式(點擊式、時間式、退出式、滾動式);2. 設計內容(標題、正文、行動按鈕);3. 設置樣式(大小、顏色、字體、背景);4. 實現代碼(HTML、CSS、JavaScript);5. 測試和部署。

See all articles