HTML5?應用程序緩存
使用 HTML5,通過創建 cache manifest 文件,可以輕松地創建 web 應用的離線版本。
什么是應用程序緩存(Application Cache)?
HTML5 引入了應用程序緩存,這意味著 web 應用可進行緩存,并可在沒有因特網連接時進行訪問。
應用程序緩存為應用帶來三個優勢:
1,離線瀏覽 - 用戶可在應用離線時使用它們
2,速度 - 已緩存資源加載得更快
3,減少服務器負載 - 瀏覽器將只從服務器下載更新過或更改過的資源。
HTML5 Cache Manifest 實例
下面的例子展示了帶有 cache manifest 的 HTML 文檔(供離線瀏覽)
<!DOCTYPE HTML>
<html manifest="demo.appcache">
<body>
文檔內容......
</body>
</html>
Cache Manifest 基礎
如需啟用應用程序緩存,請在文檔的<html> 標簽中包含 manifest 屬性:
<!DOCTYPE HTML>
<html manifest="demo.appcache">
...
</html>
每個指定了 manifest 的頁面在用戶對其訪問時都會被緩存。如果未指定 manifest 屬性,則頁面不會被緩存(除非在 manifest 文件中直接指定了該頁面)。manifest 文件的建議的文件擴展名是:".appcache"。
Manifest 文件
manifest 文件是簡單的文本文件,它告知瀏覽器被緩存的內容(以及不緩存的內容)。
manifest 文件可分為三個部分:
CACHE MANIFEST?- 在此標題下列出的文件將在首次下載后進行緩存
NETWORK?- 在此標題下列出的文件需要與服務器的連接,且不會被緩存
FALLBACK?- 在此標題下列出的文件規定當頁面無法訪問時的回退頁面(比如 404 頁面)
CACHE MANIFEST
第一行,CACHE MANIFEST,是必需的:
CACHE MANIFEST
/theme.css
/logo.gif
/main.js
上面的 manifest 文件列出了三個資源:一個 CSS 文件,一個 GIF 圖像,以及一個 JavaScript 文件。當 manifest 文件加載后,瀏覽器會從網站的根目錄下載這三個文件。然后,無論用戶何時與因特網斷開連接,這些資源依然是可用的。
NETWORK
下面的 NETWORK 小節規定文件 "login.php" 永遠不會被緩存,且離線時是不可用的:
NETWORK:
login.php
可以使用星號來指示所有其他資源/文件都需要因特網連接:
NETWORK:
*
FALLBACK
下面的 FALLBACK 小節規定如果無法建立因特網連接,則用 "offline.html" 替代 /html5/ 目錄中的所有文件:
FALLBACK:
/html/ /offline.html
注意:?第一個 URI 是資源,第二個是替補。
更新緩存
一旦應用被緩存,它就會保持緩存直到發生下列情況:
????????用戶清空瀏覽器緩存
????????manifest 文件被修改(參閱下面的提示)
????????由程序來更新應用緩存
實例 - 完整的 Manifest 文件
CACHE MANIFEST
# 2012-02-21 v1.0.0
/theme.css
/logo.gif
/main.js
NETWORK:
login.php
FALLBACK:
/html/ /offline.html
提示:以 "#" 開頭的是注釋行,但也可滿足其他用途。應用的緩存會在其 manifest 文件更改時被更新。如果您編輯了一幅圖片,或者修改了一個 JavaScript 函數,這些改變都不會被重新緩存。更新注釋行中的日期和版本號是一種使瀏覽器重新緩存文件的辦法。
關于應用程序緩存的說明
請留心緩存的內容。一旦文件被緩存,則瀏覽器會繼續展示已緩存的版本,即使您修改了服務器上的文件。為了確保瀏覽器更新緩存,您需要更新 manifest 文件。
注意:?瀏覽器對緩存數據的容量限制可能不太一樣(某些瀏覽器設置的限制是每個站點 5MB)。
HTML5?Web Workers
web worker 是運行在后臺的 JavaScript,不會影響頁面的性能。
什么是 Web Worker?
當在 HTML 頁面中執行腳本時,頁面的狀態是不可響應的,直到腳本已完成。
web worker 是運行在后臺的 JavaScript,獨立于其他腳本,不會影響頁面的性能。您可以繼續做任何愿意做的事情:點擊、選取內容等等,而此時 web worker 在后臺運行。
檢測瀏覽器是否支持 Web Worker
在創建 web worker 之前,請檢測用戶的瀏覽器是否支持它:
if(typeof(Worker)!=="undefined")
{
????????// 是的! Web worker 支持!
????//?一些代碼.....
}
????????else
{
????//抱歉! Web Worker 不支持
}
創建 web worker 文件
現在,讓我們在一個外部 JavaScript 中創建我們的 web worker。在這里,我們創建了計數腳本。該腳本存儲于 "demo_workers.js" 文件中:
var i=0;
function timedCount()
{
????i=i+1;
????postMessage(i);
????setTimeout("timedCount()",500);
}
timedCount();
以上代碼中重要的部分是 postMessage() 方法 - 它用于向 HTML 頁面傳回一段消息。
注意:?web worker 通常不用于如此簡單的腳本,而是用于更耗費 CPU 資源的任務。
創建 Web Worker 對象
我們已經有了 web worker 文件,現在我們需要從 HTML 頁面調用它。
下面的代碼檢測是否存在 worker,如果不存在,- 它會創建一個新的 web worker 對象,然后運行 "demo_workers.js" 中的代碼:
if(typeof(w)=="undefined")
{
w=new Worker("demo_workers.js");
}
然后我們就可以從 web worker 發生和接收消息了。
向 web worker 添加一個 "onmessage" 事件監聽器:
w.onmessage=function(event){
document.getElementById("result").innerHTML=event.data;
};
終止 Web Worker
當我們創建 web worker 對象后,它會繼續監聽消息(即使在外部腳本完成之后)直到其被終止為止。
如需終止 web worker,并釋放瀏覽器/計算機資源,請使用 terminate() 方法:
w.terminate();
Web Workers 和 DOM
由于 web worker 位于外部文件中,它們無法訪問下列 JavaScript 對象:
window 對象
document 對象
parent 對象
HTML5?服務器發送事件(Server-Sent Events)
HTML5 服務器發送事件(server-sent event)允許網頁獲得來自服務器的更新。
Server-Sent 事件 - 單向消息傳遞
Server-Sent 事件指的是網頁自動獲取來自服務器的更新。以前也可能做到這一點,前提是網頁不得不詢問是否有可用的更新。通過服務器發送事件,更新能夠自動到達。
例子:Facebook/Twitter 更新、股價更新、新的博文、賽事結果等。
接收 Server-Sent 事件通知
EventSource 對象用于接收服務器發送事件通知:
var source=new EventSource("demo_sse.php");
source.onmessage=function(event){?
?document.getElementById("result").innerHTML+=event.data + "<br>";};
實例解析:
創建一個新的 EventSource 對象,然后規定發送更新的頁面的 URL(本例中是 "demo_sse.php")
每接收到一次更新,就會發生 onmessage 事件
當 onmessage 事件發生時,把已接收的數據推入 id 為 "result" 的元素中
檢測 Server-Sent 事件支持
以下實例,我們編寫了一段額外的代碼來檢測服務器發送事件的瀏覽器支持情況:
if(typeof(EventSource)!=="undefined"){?
?// 瀏覽器支持 Server-Sent?
?// 一些代碼.....}
else{ /
/ 瀏覽器不支持 Server-Sent..
}
服務器端代碼實例
為了讓上面的例子可以運行,您還需要能夠發送數據更新的服務器(比如 PHP 和 ASP)。
服務器端事件流的語法是非常簡單的。把 "Content-Type" 報頭設置為 "text/event-stream"。現在,您可以開始發送事件流了
header
('Content-Type:?text/event-stream');
header('Cache-Control:?no-cache');
$time?=?date('r');
echo
"data:?The?server?time?is:?{$time}\n\n";
flush();
?>
ASP 代碼 (VB) (demo_sse.asp):
<%
Response.ContentType="text/event-stream"
Response.Expires=-1
Response.Write("data: " & now())
Response.Flush()
%>
代碼解釋:
把報頭 "Content-Type" 設置為 "text/event-stream"
規定不對頁面進行緩存
輸出發送日期(始終以 "data: " 開頭)
向網頁刷新輸出數據
EventSource 對象
在上面的例子中,我們使用 onmessage 事件來獲取消息。不過還可以使用其他事件:
onopen????????????????????????????當通往服務器的連接被打開????????
onmessage? ? ? ? ? ? ? ? ? ? ? 當接收到消息
onerror????????????????????????????當發生錯誤
HTML5 WebSocket
WebSocket 是 HTML5 開始提供的一種在單個 TCP 連接上進行全雙工通訊的協議。
WebSocket 使得客戶端和服務器之間的數據交換變得更加簡單,允許服務端主動向客戶端推送數據。在 WebSocket API 中,瀏覽器和服務器只需要完成一次握手,兩者之間就直接可以創建持久性的連接,并進行雙向數據傳輸。在 WebSocket API 中,瀏覽器和服務器只需要做一個握手的動作,然后,瀏覽器和服務器之間就形成了一條快速通道。兩者之間就直接可以數據互相傳送。
現在,很多網站為了實現推送技術,所用的技術都是 Ajax 輪詢。輪詢是在特定的的時間間隔(如每1秒),由瀏覽器對服務器發出HTTP請求,然后由服務器返回最新的數據給客戶端的瀏覽器。這種傳統的模式帶來很明顯的缺點,即瀏覽器需要不斷的向服務器發出請求,然而HTTP請求可能包含較長的頭部,其中真正有效的數據可能只是很小的一部分,顯然這樣會浪費很多的帶寬等資源。
HTML5 定義的 WebSocket 協議,能更好的節省服務器資源和帶寬,并且能夠更實時地進行通訊。
瀏覽器通過 JavaScript 向服務器發出建立 WebSocket 連接的請求,連接建立以后,客戶端和服務器端就可以通過 TCP 連接直接交換數據。
當你獲取 Web Socket 連接后,你可以通過?send()?方法來向服務器發送數據,并通過?onmessage?事件來接收服務器返回的數據。
以下 API 用于創建 WebSocket 對象。
var Socket = new WebSocket(url, [protocol] );
WebSocket 屬性
以下是 WebSocket 對象的屬性。假定我們使用了以上代碼創建了 Socket 對象:
Socket.readyState只讀屬性?readyState?表示連接狀態,可以是以下值:
0 - 表示連接尚未建立。
1 - 表示連接已建立,可以進行通信。
2 - 表示連接正在進行關閉。
3 - 表示連接已經關閉或者連接不能打開。
Socket.bufferedAmount只讀屬性?bufferedAmount?已被 send() 放入正在隊列中等待傳輸,但是還沒有發出的 UTF-8 文本字節數。
WebSocket 事件
以下是 WebSocket 對象的相關事件。假定我們使用了以上代碼創建了 Socket 對象:
openSocket.onopen????????????????????????????????????連接建立時觸發
messageSocket.onmessage????????????????????????客戶端接收服務端數據時觸發
errorSocket.onerror????????????????????????????????????通信發生錯誤時觸發
closeSocket.onclose????????????????????????????????????連接關閉時觸發
WebSocket 方法
以下是 WebSocket 對象的相關方法。假定我們使用了以上代碼創建了 Socket 對象:
Socket.send()????????????????????使用連接發送數據
Socket.close()????????????????????關閉連接