一、離線快取的起因。
HTML5之前的網頁,都是無連接,必須聯網才能訪問,這其實也是web的特色,這其實對於PC是時代問題並不大,但到了移動互聯網時代,
設備終端位置不再固定,依賴無線訊號,網路的可靠性變得降低,例如坐在火車上,過了一個隧道(15分鐘),便無法存取網站,十分不便。
而離線web應用程式允許我們在離線時與網站進行互動。
二、什麼是離線Web應程式?為什麼要開發離線的網路應用程式?
離線web應用程式是指:當客戶端本機與web應用程式的伺服器沒有建立連線時,也能正常在用戶端本機使用該web應用程式進行相關操作。
Web應用程式已經變的越來越複雜,很多領域都在利用Web應用程式。但是,它有一個致命的缺點:如果用戶沒有和Internet建立連接,他就
不能利用這個web應用程式了。因此H5新增了一個API,它使用一個本地快取機制很好的解決了這個問題,使離線應用程式的開發成為了可能。
要想讓web應用程式在離線狀態的時候也能正常運作,就必須把所有構成web應用程式的資源文件,如HTML檔案、CSS檔案、JavaScript腳本
文件等放在本機快取中,當伺服器沒有和網路建立連線時,也可以利用本機快取中的資源檔案正常執行web應用程式。
三、什麼是本機緩存,本地快取與瀏覽器網頁快取的差別。
Web應用程式的本機快取與瀏覽器的網頁快取有許多方面都存在著明顯的差異。
1.本地快取為整個web應用程式服務的,而瀏覽器的網頁快取只服務單一網頁。任何網頁都具有網頁快取。而本地緩存至緩存那些指定的快取
的頁面。
2.網頁快取不安全且不可靠,因為我們不知道網站中到底快取了哪些網頁,以及快取了網頁上的哪些資源。而本地緩存可靠,我們可以控制對
哪些內容進行緩存,
不對哪些內容進行緩存,開發人員還可以利用編程的手段來控制緩存的更新,利用緩存對象的各種屬性、狀態和事件來開發出更強大的離線
應用程式。
3.(有些)瀏覽器會主動保存自己的快取檔案以加快網站載入速度。但是要實現瀏覽器快取必須要滿足一個前提,那就是網路必須保持連線
。如果網路沒有連接,
即使瀏覽器啟用了對一個網站的緩存,仍然無法開啟這個網站。只會收到一封錯誤訊息。而使用離線web應用,我們可以主動告訴瀏覽器應該
從網站伺服器中獲取或緩存哪些文件,並且在網絡離線狀態下仍然能夠訪問這個網站。
四、如何實作HTML5應用程式快取?什麼是manifest文件,在文件中製定什麼內容需要進行本地緩存,哪些內容不需要?
實作HTML5應用程式快取非常簡單,只需三步,且不需要任何API。只需要告訴瀏覽器需要離線快取的文件,並對伺服器和網頁做一些
簡單的設定即可實現。
4-1、建立一個 cache.manifest 文件,並確保文件有正確的內容。
4-2、在伺服器上設定內容類型。
4-3、所有的HTML檔案都指向 cache.manifest。
具體實作:
4-1:首先我們建立一個名為cache.manifest的文件,Windows平台下用記事本即可(也可用其他的IDE)。文件內容如下:
注意事項:
1、第一行必須是」CACHE DMANIFEST」文字,以便把本文件的作用告知瀏覽器,即對本機快取中的資源檔案進行具體設定。
2、在manifest檔中,可以加上註解來做一些必要說明或解釋。註解行以”#”文字開頭。
3、CACHE之後的部分為列出我們需要快取的檔案。
4、在FALLBACK之後的部分每一行中指定兩個資源文件,第一個資源文件為能夠在線訪問時使用的資源文件,第二個資源文件為
#不能在線存取時使用的備用資源檔案。
5、在NETWORK之後可以指定線上白名單,也就是列出我們不希望離線儲存的文件,因為通常它們的內容需要網路存取才有意義。
另外,在此部分我們可以使用捷徑:通配符*。這將告訴瀏覽器,應用程式伺服器中取得沒有在顯示部分中提到的任何檔案或URL。
4-2:在伺服器上設定內容類型。
真正運行或測試離線web應用程式的時候,需要對伺服器進行配置,讓伺服器支援text/cache-manifest這個MIME類型(在h5中規定
manifest檔案的MIME類型是text/cache-manifest)。例如對Apache伺服器進行設定的時候,需要找到
{apache_home}/conf/mime.type這個檔案(.htaccess),並在檔案最後加上如下所示程式碼:
text /cache-manifest .manifest 。在微軟的IIS伺服器中的步驟如下所示:
(1).右鍵選擇預設網站或需要新增類型的網站,彈出屬性對話框
(2).選擇」http頭」標籤
(3)。在MIME映射下,按一下檔案類型按鈕
(4).在開啟的MIME類型對話方塊中按一下新按鈕
(5).在關聯副檔名文字中輸入”manifest”,在內容類型文字方塊中輸入”text/cache-manifest”,然後點選確定按鈕。
4-3:設定HTML檔案的指向。
<html manifest=”/cache.manifest” >
完成這一步驟後,就完成了web離線快取的所有步驟。由於瀏覽的文件內容都沒有更改且儲存在本地,因此現在網頁的開啟速度會更快
(即使是線上狀態也如此)。
注意事項:
1、網站的每個html頁面都必須設定html元素的manifest屬性。 Must to do;
2、在你的整個網站應用程式中,只能有一個cache.manifest檔(建議放在網站根目錄下);
3、部分瀏覽器(如IE8-)不支援HTML5離線快取;
4、「#」 開頭的註解行可滿足其他用途。應用程式的快取會在其 manifest 檔案更改時被更新。如果您編輯了一幅圖片,或者修改了一個 JavaScript 函數,
這些改變都不會重新快取。更新註解行中的日期和版本號碼是一種使瀏覽器重新快取檔案的方法。
五、掌握進行本機快取的applicationCache物件及其屬性與事件:
(1)快取的更新:
當一個web應用程式從快取載入的時候,所有與之相關的文件也是直接從快取中取得。在線上狀態下,瀏覽器會非同步地檢查清單檔案是否有更新。
如果有更新,新的清單檔案以及清單中的列舉的所有檔案都會下載下來重新儲存到程式快取中。但要注意瀏覽器只是檢查清單文件,而不會
檢查快取的文件是否有更新,如果修改一個快取的js文件,並且要想讓該文件生效,就必須去更新下清單文件。由於應用程式所依賴的文件列
表其實並沒有變化,因此最簡單的方式就是更新版本。
程式碼如下:
CHCHE MANIFEST CACHE: #version<span style="color:#cc0000;">2</span> (更改这个数字以便让浏览器重新下载) myapp.html myapp.css myapp.js
同樣「卸載“,就要在伺服器端刪除清單文件,使得請求該文件的時候返回404,同時,修改html檔案以便他們與該清單清單」斷開連結「。
注意:
①、瀏覽器檢查清單檔案、更新快取的操作是非同步的,可能是在從快取中載入應用程式之前,也有可能同時進行。因此對於簡單的web應用程式
而言,在更新清單檔案之後,使用者必須載入應用程式兩次才能保證最新的版本生效:第一次是從快取中載入舊版本隨後更新快取;第二次才是從
快取中載入最新的版本。
②、瀏覽器在更新快取過程中會觸發一系列事件,可以透過註冊處理程序來追蹤這個過程同時提供回饋使用者。
程式碼如下:
applicationCache.onupdateready= function(){ var reload = confirm(“A new version of this application is available\n and will be used the next time you reload.\n”); if(reload) location.reload(); }
該事件註冊在ApplicationCache物件上的,該物件是window的applicationCache屬性的值。支援應用程式快取的瀏覽器會定義該屬性。
(2)處理應用程式快取相關事件:
//下面所有的事件处理程序都使用此函数来显示状态消息 //由于都是通过调用status函数来显示状态,因此所有处理程序都返回false来阻止浏览器显示其默认状态消息 function status(msg){ doucment.getElementById(“statusline”).innerHTML= msg; console.log(msg); //同时在控制台输出此消息,便于调试 } //每当应用程序载入的时候,都会检查该清单文件 //也总会首先触发“checking”事件 window.applicationCache.onchecking = function(){ status(“checking for a new version.”); return false; } //如果没有改动,同时应用程序也已经缓存了 //”noupdate”事件被触发,整个过程结束 window.applicationCache.onnoupdate = function(){ } //如果还未缓存应用程序,或者清单文件有改动 //那么浏览器会下载并缓存清单中的所有资源 //触发”downloading”事件,同时意味着下载过程开始 window.applicationCache.ondownloading = function(){ status(“Downloading new version”); window.progresscount = 0; return false; } //在下载过程中会间断性触发“progress“事件 //通常是在每个文件下载完毕的时候 window.applicationCache.onprogress = function(e){ varprogress = “”; if(e && e.lengthComputable) progress = “ ”+Math.round(100*e.loaded/e.total)+”%” else progress = “(“+(++progresscount)+”)” return false; } //当下载完成并且首次将应用程序下载到缓存中时,浏览器会触发“cached“事件 window.applicationCache.oncached = function(e){ status(“Thisapplication is now cached locally”); return false; } //当下载完成并将缓存中的应用程序更新后,浏览器会触发”updaterady”事件 //要注意的是:触发此事件的时候,用户任然可以看到老版本的应用程序 window.applicationCache.onupdateready = function(e){ status(“Anew version has been downloaded. Reload to run it”); return false; } //如果浏览器处于离线状态,检查清单列表失败,则会触发“error“事件 //当一个未缓存的应用程序引用一个不存在的清单文件,也会触发此事件 window.applicationCache.onerror = function(e){ status(“Couldn’tload manifest or cache application”); return false; } //如果一个缓存的应用程序引用一个不存在的清单文件,会触发“obsolete“ //同时将应用从缓存中移除之后不会从缓存而是通过网络加载资源 window.applicationCache.onobsolete = function(e){ status(“Thisapplication is no longer cached. Reload to get the latest version from thenetwork.”); return false; }
每次載入一個設定了manifest屬性的html文件,瀏覽器都會觸發」checking」事件。並透過網路載入該清單檔案。不過之後,會隨著
不同的情況觸發不同的事件。
事件清單:
(1).沒有可用更新
如果應用程式已經快取且清單檔案沒有動,則瀏覽器會觸發noupdate事件
(2).有可用更新
如果應用程式已經快取且清單元件有改動,則瀏覽器會觸發downloading事件並開始下載和快取清單檔案中列出的所有資源。
隨著下載過程的進行瀏覽器也會觸發”progress」事件,在下載完成後,會觸發”updateready」事件。
(3).首次載入新的應用程式
如果還未快取應用程序,如上所述downloading,progress事件都會觸發。但是,當下載完成後,瀏覽器會觸發”cached”事件
而不是updateready事件
(4)。瀏覽器處於離線狀態
如果瀏覽器處於離線狀態,它無法檢查清單文件,同時它會觸發「error」事件。
如果一個未快取的應用程式引用了不存的清單文件,瀏覽器也會觸發該事件
(5).清單文件不存在
如果瀏覽器處理線上狀態,應用程式也已經快取起來,但是清單檔案不存在,瀏覽器會觸發obsolete事件,並將該應用程式
從快取中移除。
快取狀態:
缓存的状态可以通过window.applicationCache.status获得,其状态主要包括如下6种:
const unsigned short UNCACHED=0;//未缓存(应用程序没有设置manifest属性:未缓存) const unsigned short IDLE=1;//空闲状态(清单文件已经检查完毕,并且已经缓存了最新的应用程序) const unsigned short CHECKING=2;//检查中(浏览器正在检查清单文件) const unsigned short DOWNLOADING=3;//下载中(浏览器正在下载并缓存清单中列举的所有文件) const unsigned short UPDATEREADY=4;//更新准备中(已经下载和缓存了最新版的应用程序) const unsigned short OBSOLETE =5;//过期状态(清单文件不存在,缓存将被清除) readonly attribute unsigned short status;
六、ApplicationCache对象还定义了两个方法update()和swapCache():
(1).update
显式调用了更新缓存算法以检测是否有最新版本的的应用程序。这导致浏览器检测同一个清单文件(并触发相同的事件),
这和第一次载入应用程序时的效果是一样的。
(2).swapCache
它告诉浏览器可以弃用老缓存,所有的请求都从新缓存中获取。注意,这并不会重新载入应用程序:所有已经载入的html文件
、图片、脚本等资源都不会改变。但是,之后的请求将从最新的缓存中获取。这会导致“版本错乱”的问题,因此一般不推荐使用
,除非应用程序设计得很好,确保这样的方式没有问题。只有ApplicationCache.UPDATEREADY和
ApplicationCache.ABSOLETE 时调用 swapCache()才有意义(当状态OBSOLETE时,调用它可以立即弃用废弃的缓存,
让之后所有的请求都通过网络获取)。如果状态属性是其他数值的时候调用swapCache()方法,它就会抛出异常。
七、如何判断在线还是离线状态?
离线web应用指的是将自己“安装”在应用程序缓存中的程序,使得哪怕在浏览器处于离线状态时依然可访问它。为了在离线状态可用,
Web应用需要可以告知别人自己是离线还是在线,同时当网络连接的状态发生改变时候也能“感知”到。通过navigator.onLine属性,
navigator.onLine是HTML5定义用来检测设备是在线还是离线。对应的值为false或true。但是不同浏览器表现并不一致。
IE 6+和Safari 5+能够正确的检测到网络已断开,并将navigator.onLine设为flase。
Firefox 3+和Opera 10.6+也支持navigator.onLine。但需要手动讲浏览器设置为脱机模式才能让浏览器正常工作。
Chrome 11及以上版本始终将navigator.onLine设为true。(不过作者的Chrome 21已经能正常使用了)
HTML5定义了online&offline事件用于监听网络状态变化。
window.addEventListener('online', callback); // 离线到上线
window.addEventListener('offline', callback); // 上线到离线
目前除了IE(IE只支持navigator.onLine属性)外,其他最新浏览器都支持这个事件。
八、离线Web应用实战。
通过一个简单的记事本程序——PermaNote,来解释如何使用。程序将用户的文本保存到localStorage中,并且在网络连接可用的时候,
将其上传到服务器,PermaNote只允许用户编辑单个笔记。
PermaNote应用包含3个文件,一个应用清单文件、一个html页面文件,一个实现逻辑的js文件。
Demo: http://xuanfengge.com/demo/201506/appcache/permanote.html
①.premanote.appcache部分:
CACHE MANIFEST # PermaNote v8 permanote.html permanote.js NETWORK: note
②.permanote.html部分:
<!DOCTYPEHTML> <html manifest= permanote.appcache”> <head> <title>PermaNote Editor</title> <script src=” permanote.js”></script> <style type=”text/css”> #editor {width:100%;height:250px} #statusline{width:100%} </style> </head> <body> <p id=”toobar”> <button id=”savebutton”onclick = “save()”>save</button> <button onclick = “sync()”>SyncNote</button> <button onclick = “applicationCache.update()”>UpdateApplication</button> <textarea id=”editor”></textarea> <p id=”statusline”></p> </p> </body> </html>
③.permanote.js部分
status()函数用于显示状态栏消息,save()函数将笔记本保存到服务器,sync()用于确保本地与服务器文本的同步。
应用程序的时间处理程序解释:
(1).onload
尝试和服务器同步,一旦有新版本的笔记并且完成同步后,就启用编辑器窗口。
save()和sync()函数发出HTTP请求,并在XMLHttpRequest对象上注册一个onload时间处理程序来获取上传或者
下载完成的提醒。
(2).onbeforeunload
在未上传前,把当前版本的笔记数据保存到服务器上。
(3).oninput
每当textarea输入框内容发生变化时,都将其内容保存到localStorage中,并启动一个计时器。当用户停止编辑超过5秒
,将自动把数据保存到服务器。
(4).onoffline
当浏览器进入离线状态时,在状态栏显示离线消息。
(5).ononline
当浏览器回到在线状态时,同步服务器,检查是否有新版本的数据,并且保存当前版本的数据。
(6).onupdateready
如果新版本的应用已缓存,则在状态栏展示消息告知用户。
(7).onnoupdate
如果应用程序缓存没有发生变化,则同时用户仍在运行当前版本。
###
以上是HTML5新特性之離線快取技術-php中文網的詳細內容。更多資訊請關注PHP中文網其他相關文章!