您好,登錄后才能下訂單哦!
這篇文章主要介紹了移動Web離線應用的示例分析,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。
先決條件
在本文中,您將使用最新 Web 技術開發 Web 應用程序。這里的大多數代碼只是 HTML、JavaScript 和 CSS — 任何 Web 開發人員的核心技術。需要的最重要的東西是用于測試代碼的瀏覽器。本文中的大多數代碼將運行在最新的桌面瀏覽器上,例外的情況會指出來。當然,還必須在移動瀏覽器上進行測試,您肯定希望最新的 iPhone 和 Android SDK 支持這些代碼。本文中使用的是 iPhone SDK 3.1.3 和 Android SDK 2.1。
為何要支持您的應用程序離線工作?
由于幾個原因,離線 Web 應用程序對于用戶和開發人員都有吸引力。許多開發人員希望能夠編寫一個能夠在所有最流行的智能手機上運行的 Web 應用程序,而不是為每個平臺編寫本機應用程序。這對開發人員很方便,但并不意味這這是用戶的愿望。為實現上述目標,移動 Web 應用程序必須能夠提供本機移動應用程序能夠提供的許多(或絕大部分)相同的特性。離線工作肯定是其中一個特性。有些應用程序非常依賴來自 Internet 的數據和服務 — 不管它們是移動 Web 還是本機應用程序。但是,應用程序不能僅僅因為用戶的連接不好而完全失敗。但這正是傳統 Web 應用程序的癥結所在。
離線功能使移動 Web 應用程序類似于本機應用程序。此外,離線功能還有其他好處。Web 瀏覽器總是緩存靜態資源。它們依賴通過您的 Web 服務器發送的 HTTP 響應頭部中的元數據來檢索渲染頁面所需的 HTML、JavaScript、CSS 和圖像。如果渲染頁面所需的所有資源都已緩存,那么頁面就可以非常迅速地加載。但是,如果某個資源沒有緩存,那么它將極大地降低頁面載入速度。這種情況經常發生,實在是讓人無法忍受。也許一個 CSS 文件擁有一個與其他所有文件都不同的 Cache-Control 頭部,或者,也許是瀏覽器因為耗盡了已分配空間而無法緩存。
使用離線應用程序,您可以確保所有資源都會被緩存。瀏覽器將總是從緩存加載所有資源,盡管您也能夠控制哪些資源從緩存加載。一種常見的 Ajax 技巧是將一個額外的時間戳參數添加到 Ajax GET 請求(或者,更糟糕的是在應該使用 GET 時使用 POST)來避免瀏覽器緩存一個響應。您無需使用這種技巧來支持離線 Web 應用程序。
離線應用程序聽起來挺棒,那么創建一個離線應用程序一定很復雜,對吧?實際上,創建方法非常簡單,只需完成下面三個步驟:
創建一個在線清單文件。
告知瀏覽器這個清單文件。
設置服務器上的 MIME 類型。
離線清單
創建過程涉及一個關鍵文件:您的應用程序的緩存清單。這個文件告知瀏覽器要緩存(或者,不緩存)的確切內容。這成為您的應用程序的事實來源。清單 1 展示了一個簡單緩存清單示例。
清單 1. 簡單緩存清單
JavaScript Code復制內容到剪貼板
CACHE MANIFEST
# Version 0.1
offline.html
/iui/iui.js
/iui/iui.css
/iui/loading.gif
/iui/backButton.png
/iui/blueButton.png
/iui/cancel.png
/iui/grayButton.png
/iui/listArrow.png
/iui/listArrowSel.png
/iui/listGroup.png
/iui/pinstripes.png
/iui/redButton.png
/iui/selection.png
/iui/thumb.png
/iui/toggle.png
/iui/toggleOn.png
/iui/toolbar.png
/iui/whiteButton.png
/images/gymnastics.jpg
/images/soccer.png
/images/gym.jpg
/images/soccer.jpg
這個文件列示了您的應用程序正常工作所需的所有文件,其中包括 HTML 文件、JavaScript、 CSS 和圖像。它還可以包括視頻、PDFs、XML 文件,等等。注意,本示例中的所有 URLs 都是相對的。任何相對 URLs 必須相對于緩存清單文件。在本例中,緩存清單文件位于您的 Web 應用程序的根目錄。比較 清單 2 中的目錄結構和 清單 1 中的相對 URLs。
清單 2. Web 應用程序的文本版目錄結構
JavaScript Code復制內容到剪貼板
Name
V images
gymnastics.jpg
soccer.png
V iui
backButton.png
blueButton.png
cancel.png
grayButton.png
iui.css-logo-touch-icon.png
iui.css
iui.js
iuix.css
iuix.js
listArrow.png
listArrowSel.png
listGroup.png
loading.gif
pinstripes.png
redButton.png
selection.png
thumb.png
toggle.png
toggleOn.png
toolbar.png
toolButton.png
whiteButton.png
manifest.mf
offline.html
> WEB-INF
您可能已經注意到,這個應用程序正在使用 iUI 框架。這個一個流行的 JavaScript+CSS 工具包,用于向移動 Web 應用程序提供本機 iPhone 應用程序觀感。如 清單 1 和 清單 2 所示,這個框架使用幾個圖像來伴隨它的 JavaScript 和 CSS 文件。但是,只要列示在清單中,所有這些文件都將被瀏覽器緩存并可在離線模式中使用。
清單 1 中另一個需要注意的關鍵點是版本信息,它并不是規范的一部分。事實上,它只是文件中的一個注釋。但是,擁有這樣的信息很關鍵,因為您可以使用該信息來告知瀏覽器您的應用程序有一個新版本。想想看,假如您更改了一些 HTML 或 JavaScript,或者甚至只是更換了一個圖像。如果您不修改清單,則瀏覽器永遠不會費心去加載修改后的資源的新版本。緩存清單沒有過期一說,因此所有資源都將保持緩存狀態,除非用戶清空緩存或清單文件更改。瀏覽器將檢查是否存在新的清單文件。要表明一個新的清單文件,您只需更改現有清單文件的部分或全部內容。返回到您的修改頁面上的 HTML 的示例,如果您更改了 HTML 并更改了清單文件中的版本字符串,那么瀏覽器將知道資源已經被更改并再次下載它們。將版本號放置到注釋中是管理這個生命周期的一種簡單方法。
告知瀏覽器關于清單的信息
要啟用您的 Web 應用程序的離線緩存,還需要向瀏覽器提供一些信息。Web 瀏覽器需要知道您想啟用緩存,以及到哪里去找到您的緩存清單文件。清單 3 展示了一種非常簡單的方法。
清單 3. 啟用了離線功能的 Web 頁面
XML/HTML Code復制內容到剪貼板
<!DOCTYPE html>
<html>
<html manifest="manifest.mf">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<meta name="viewport" content="width=device-width; initial-scale=1.0;
maximum-scale=1.0; user-scalable=0;"/>
<meta name="apple-touch-fullscreen" content="YES" />
<link rel="apple-touch-icon" href="/iui/iui-logo-touch-icon.png" />
<style type="text/css" media="screen">@import "/iui/iui.css";</style>
<script type="application/x-javascript" src="/iui/iui.js"></script>
<title>Let's do it offline</title>
</head>
<body>
<div class="toolbar">
<h2 id="pageTitle">Going offline</h2>
<a id="backButton" class="button" href="#"></a>
</div>
<ul id="menu" title="Sports" selected="true">
<li><a href="#gym"><img height="80" width="80"
src="/images/gym.jpg" align="middle"/>
<span style="display:inline-block;
vertical-align:middle">Gymnastics</span></a></li>
<li><a href="#soccer"><img src="/images/soccer.jpg"
align="middle"/>
<span style="display:inline-block;
vertical-align:middle">Soccer</span></a></li>
</ul>
<div id="gym" title="Gymnastics" class="panel">
<img src="/images/gymnastics.jpg" alt="Boys Gymnastics"/>
</div>
<div id="soccer" title="Soccer" class="panel">
<img src="/images/soccer.png" alt="Boys Soccer"/>
</div>
</body>
</html>
這個 HTML 最重要的一點是根 html 元素。注意,該元素擁有一個稱為 manifest 的屬性。正是這個屬性告知瀏覽器這個頁面可以離線工作。manifest 參數的值是到該 Web 頁面的緩存清單文件的 URL。重申一遍,這個 URL 可以是一個完整 URL,盡管它在這里是一個相對(于指定 Web 頁面的)URL。這里需要注意的另一點是該頁面的 DOCTYPE。這是用于 HTML 5 Web 頁面的規范 doctype。離線 Web 應用程序規范并不強制您使用這個 DOCTYPE;但是,建議您這樣做。否則,某些瀏覽器可能不會將頁面識別為 HTML 5 頁面,并且可能會忽略緩存清單。這個 HTML 的剩余部分只是使用 iUI 的一個簡單示例。圖 1 展示了這個頁面在 iPhone 模擬器上的外觀。
圖 1. 運行在 iPhone 模擬器上的離線 Web 應用程序
屏幕截圖,展示運行在 iPhone 模擬器上的離線 Web 應用程序:帶有 Gymnastics 和 Soccoer 選項的 Sports 應用程序
測試離線應用程序可能有點麻煩。如果可能,最簡單的測試方式是將您的應用程序部署到一個 Web 服務器上。然后,您可以訪問這個頁面一次,關閉您的 Internet 連接,然后嘗試再次訪問。如果出現任何失敗,那么您可能在緩存清單中遺漏了一些文件。在進行上述測試之前,您需要對您的 Web 服務器進行一些關鍵配置。
Web 服務器配置
清單 3 展示您通過使用您的 Web 頁面的根 html 元素上的 manifest 屬性來表明您的緩存清單的位置。但是,緩存清單規范規定,瀏覽器在下載和處理緩存清單時必須執行一個額外的驗證步驟,即檢查緩存清單的 MIME 類型,該類型必須為 text/cache-manifest。通常,這意味著您需要配置您的 Web 服務器來設置一個靜態文件的 MIME 類型,或者,您必須編寫一些代碼來動態創建該文件并設置 MIME 類型。前者當然是更有效的方法,但是有時您需要使用后一種方法,比如您沒有對服務器配置的控制權(比如在一個共享或托管環境中)。如果您對服務器擁有控制權且正在使用一個 Java™ 應用程序服務器,您可以在 Web 應用程序的 web.xml 文件中配置這個參數。清單 4 展示了一個配置示例:
清單 4. 配置 web.xml 來設置 MIME 類型
XML/HTML Code復制內容到剪貼板
<?xml version="1.0" encoding="utf-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
<!-- Servlets go here -->
<mime-mapping>
<extension>mf</extension>
<mime-type>text/cache-manifest</mime-type>
</mime-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
</web-app>
顯然,這里的關鍵部分是 mime-mapping 元素。在本例中,您的設置的含義是:對于以 .mf 擴展名結尾的任意文件,將它們的 MIME 類型設置為 text/cache-manifest。當然,一種甚至更有效的方法是從專用于提供靜態內容的服務器(比如一個 Apache Web 服務器)提供這樣的文件。在一個典型 Apache 安裝中,您只需修改 httpd/conf 目錄中的 mime.types 文件,如 清單 5 所示。
清單 5. 在 mime.types 中設置 MIME 類型
JavaScript Code復制內容到剪貼板
# This file controls what Internet media types are sent to the client for
# given file extension(s). Sending the correct media type to the client
# is important so they know how to handle the content of the file.
# Extra types can either be added here or by using an AddType directive
# in your config files. For more information about Internet media types,
# please read RFC 2045, 2046, 2047, 2048, and 2077. The Internet media type
# registry is at <http://www.iana.org/assignments/media-types/>.
# MIME type Extensions
text/cache-manifest mf
# many more mappings...
在這兩個示例中,您都使用 mf 作為您的清單文件的擴展名,因此該文件是 manifest.mf。這個擴展名可以任意選擇,您可以使用 .manifest 或 .foo,只要這個清單文件的擴展名匹配在您的配置文件中的映射中使用的擴展名。注意,其他應用程序和 Web 服務器可能擁有不同的配置機制。現在您已經看到了使用 HTML 5 創建離線移動 Web 應用程序中的關鍵因素,下面我們來看一個更復雜的示例,探索離線移動 Web 應用程序的更多功能。
高級示例
在上一個示例中,所有內容都是靜態的。能夠以離線模式看到所有內容讓人感覺不錯,但更典型的應用程序需要從它的服務器和 Web 服務讀取動態數據。為使您的示例更真實,可以拖入一些來自 Twitter 的數據。如果您閱讀了本系列之前的文章,那么您將對此感到熟悉(參見 參考資料)。首先,在 清單 6 中查看這個示例修改后的 HTML。
清單 6. 修改后的 HTML
XML/HTML Code復制內容到剪貼板
<body onload="init()">
<div class="toolbar">
<h2 id="pageTitle">Going offline</h2>
<a id="backButton" class="button" href="#"></a>
</div>
<ul id="menu" title="Sports" selected="true">
<li><a href="#gym">
<img height="80" width="80" src="/images/gym.jpg" align="middle"/>
<span style="display:inline-block; vertical-align:middle">Gymnastics</span>
</a></li>
<li><a href="#soccer"><img src="/images/soccer.jpg" align="middle"/>
<span style="display:inline-block; vertical-align:middle">Soccer</span>
</a></li>
<li id="online" style="display: none"><img src="/images/online.jpg"/></li>
</ul>
<ul id="gym" title="Gymnastics"></ul>
<ul id="soccer" title="Soccer"></ul>
</body>
主要區別是現在列示了 gym 和 soccer 元素,且這兩個元素為空。您將分別使用來自 Twitter 的關于體操和足球的 tweets 來填充它們。還要注意一個 id 為 online 的列表項元素,該元素顯示一個圖像,用于向用戶表明應用程序是在線還是離線。但是,這個元素默認隱藏,也就是說,默認模式是離線。 這個 body 元素規定:一旦這個 body 加載,就會調用一個 init() 函數。清單 7 展示了這個函數。
清單 7. 頁面初始化 JavaScript
JavaScript Code復制內容到剪貼板
function init(){
if (navigator.onLine){
searchTwitter("gymnastics", "showGymTweets");
searchTwitter("soccer", "showSoccerTweets");
$("online").style.display = "inline";
}
gymTweets = localStorage.getItem("gymnastics");
if (gymTweets){
gymTweets = JSON.parse(gymTweets);
showGymTweets();
}
soccerTweets = localStorage.getItem("soccer");
if (soccerTweets){
soccerTweets = JSON.parse(soccerTweets);
showSoccerTweets();
}
document.body.addEventListener("online", function() {
$("online").style.display= "inline";
applicationCache.update();
applicationCache.addEventListener("updateready", function() {
applicationCache.swapCache();
}, false);
}, false);
document.body.addEventListener("offline", function() {
$("online").style.display = "none";
}, false);
}
這個代碼所做的第一件事就是檢查您是在線還是離線。如果在線,則顯示在線圖像。更重要的是,如果您在線,那么它將通過調用searchTwitter 函數來從 Twitter 加載數據。同樣,這是一種允許您使用 JSONP 直接從瀏覽器搜索 Twitter 的技術(在本系列前面的文章中解釋 — 參見 參考資料)。接下來,試圖從 localStorage 加載現有 tweets。如果您熟悉 localStorage,就會知道這是另一個能夠在離線模式下很好地工作的 HTML 5 功能。參閱本系列第 2 部分進一步了解它(參見 參考資料)。注意,為進行新搜索(在檢測到您處于在線時啟動)并加載本地保存的 tweets,showGymTweets 和 showSoccerTweets 函數將被調用。它們是相似的函數,清單 8展示了 showGymTweets。
清單 8. 顯示 Gym tweets
JavaScript Code復制內容到剪貼板
function showGymTweets(response){
var gymList = $("gym");
gymList.innerHTML = "";
if (gymTweets){
if (response){
gymTweets = response.results.reverse().concat(gymTweets);
}
} else {
gymTweets = response.results.reverse();
}
showTweets(gymTweets, gymList);
localStorage.setItem("gymnastics", JSON.stringify(gymTweets));
}
這個函數能夠顯示本地存儲的 tweets,來自 Twitter 的新 tweets,或者二者的結合(如果二者都存在)。最重要的是,它本地存儲所有資源,構建您的本地 tweets 數據緩存。這是用于同時管理本地緩存的數據和來自服務器的實時數據的典型代碼。它允許應用程序順暢運行,無論在線還是離線。
返回到 清單 7,需要做的最后一件事是注冊事件處理程序。這將告知您瀏覽器的在線或離線狀態何時改變。至少,您可以更改在線圖像,并在是否顯示圖像之間切換。在這個應用程序從離線轉為在線的例子中,您訪問 applicationCache 對象。這個對象表示按照緩存清單中的聲明方式緩存的所有資源。在本例中,您調用它的 update 方法。該方法指示瀏覽器檢查它是否檢測到 applicationCache的一個更新。如前所述,瀏覽器首先檢查緩存清單文件的一個更新。您添加另一個事件監聽器來檢查可用緩存的一個更新。如果存在更新,則調用 applicationCache 上的 swapCache 方法。該方法將重新加載在緩存清單文件中指定的所有文件。
談到緩存清單文件,您需要對這個高級示例進行最后的完善。緩存清單文件需要按 清單 9 所示修改。
清單 9. 修改后的緩存清單
JavaScript Code復制內容到剪貼板
CACHE MANIFEST
# Version 0.2
CACHE:
offline.html
json2.js
/iui/iui.js
/iui/iui.css
/iui/loading.gif
/iui/backButton.png
/iui/blueButton.png
/iui/cancel.png
/iui/grayButton.png
/iui/listArrow.png
/iui/listArrowSel.png
/iui/listGroup.png
/iui/pinstripes.png
/iui/redButton.png
/iui/selection.png
/iui/thumb.png
/iui/toggle.png
/iui/toggleOn.png
/iui/toolbar.png
/iui/whiteButton.png
/images/gym.jpg
/images/soccer.jpg
/images/online.jpg
NETWORK:
http://search.twitter.com/
在這個示例中,您將一個顯式 CACHE 區域添加到清單。清單可以擁有多個不同的區域,但是,如果它只有一個區域,那么這個區域就假定為 CACHE 且可以省略。這里之所以要使用顯式區域,其原因是您還有一個 NETWORK 區域。這個區域向瀏覽器表明:來自指定域(這里是 search.twitter.com)的任何數據都應該從網絡獲取且從不緩存。由于您正在本地緩存來自 Twitter 的搜索結果,您肯定不希望瀏覽器再執行間接的查詢緩存。現在,這段代碼就位后,應用程序將總是從 Twitter 加載實時 tweets。但是,它將總是緩存那些 tweets 并使它們對用戶可用,即使在用戶的設備喪失連通性時。
結束語
自從 Mosaic 瀏覽器風靡以來,Web 應用程序已經走過了漫長的發展歷程。移動 Web 應用程序發展得甚至更快。只使用 Wireless Markup Language (WML) 的 WAP 手機的日子走到頭了。現在您對您的移動瀏覽器提出要求甚至比它們的桌面瀏覽器還要多。離線功能就是這樣的要求之一。HTML 5 中的標準經歷了很長時間,以簡化開發人員離線支持他們的移動 Web 應用程序的工作。在本系列下一篇文章中,您將看到另一個 HTML 5 標準 —— Web Workers —— 如何極大地改善移動 Web 應用程序的性能。
感謝你能夠認真閱讀完這篇文章,希望小編分享的“移動Web離線應用的示例分析”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業資訊頻道,更多相關知識等著你來學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。