html5帶給我們的不僅僅是更多語義豐富的標簽,還有更多更牛逼的特性,比如“離線存儲”。 對於台式電腦來說,或者它並沒有帶來什麼驚喜,但是對於移動設備來說離線存儲簡直就是一個神跡。對於任何擁有支持離線存儲浏覽器的移動設備,比如iphone,ipod touch,離線存儲使得web前端工程師可以很容易的針對它們開發應用程序。
前面吹噓了一段,不過說實在的,html5本地存儲就目前來說還是很受限的。其一,浏覽器限制,目前只有 Safari 3.1 and later, and in iPhone OS 2.0 and later. 提供了javascript database 原生支持,不過也有 Taffy DB 可以曲線救國。(還沒有用過,不敢妄下結論。)。 其二,服務器端需要修改配置,旦如果是自己的服務器就很簡單了。
下面就以一個簡單的offline web app-note book 為例,記錄一下為iphone/ipod touch開發web app的過程。不是經驗,只是初探。
首先,適合iphone/ipod touch 的UI 它並不是本文的重點,有興趣的同學可以移步這裡 。這裡只強調一點:你默認做的頁面,放到iphone看會變的很窄,字很小。這是因為iphone用它320px寬的屏幕顯示了一個默認980px寬的頁面,你的內容被按比例縮小了。要解決這個問題很簡單,只要在html的head區域加一個meta標記,具體語法請看這裡 。 也就是這樣:
這個問題解決之後我們就可以肆意的使用html5和css3來打造界面了,(針對設備開發可以不考慮兼容性,真是暢快淋漓呀。)
我大概做了個丑陋的界面:
html代碼, CSS代碼 (其實你可以不用看,最後有打包的代碼)
完成了UI,我們就需要對數據進行處理了。
在開始“數據”的本地存儲之前,我們先來了解一下client-side database storage API:
the client-side database storage API allows web applications to store structured data locally using a medium many web developers are already familiar with – SQL.--webkit blog
目前只有webkit核心的浏覽器支持這一特性。你甚至都不能在w3c的html5工作草案中找到 (cs-db)client-side database 的詳細描述。
首先我們要嘗試建立一個數據庫鏈接:
try { if(!window.openDatabase){ //檢測浏覽器是否支持cs-db alert('not supported cs-db!'); } else { var shortName = 'noteDB'; var version = '1.0'; var displayName = 'Note book database'; var maxSize = 65536; //創建一個數據庫 var db = openDatabase(shortName,version,displayName,maxSize); } } catch(e){ //嘗試捕獲錯誤 if (e == 2){ alert('Invalid database version.'); } else { alert("Unknown error "+e+"."); } }
如果以上代碼無誤,你就會在safair或者chrome的開發者工具中看到這個數據庫:
在右側區域可以直接執行一些sql查詢,但是我總是得到 “發生意外錯誤“0”。” 這樣的結果,不知道是不是RP的問題。
接下來就是創建表,以及執行一些sql語句進行增刪改查。
js執行sql的基本語法大致是這樣的:
db.transaction( function (transaction){ transaction.executeSql(sqlquery,[],dataHandler, errorHandler); } );
其中transaction.executeSql中參數依次為:sql查詢字符串,傳遞給sql查詢的參數,數據處理句柄,錯誤處理句柄。其中只有第一項為必選,其余都為可選項。
第二個參數的用法大致是這樣的:
transaction.executeSql("UPDATE people set age=? where name=?;",[ age, name ]);
查詢字符串中的“ ?” 會被後面數組中的變量依次替換。
注意:以上我用了“大致”這個詞,因為沒有官方的文檔 (W3C-web database),只是從一些其它文獻以及自己判斷得來,若有錯誤還請指正。
下面我們創建一張用來存儲note的表:
db.transaction( function (transaction){ transaction.executeSql( 'CREATE TABLE IF NOT EXISTS notes (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,titel TEXT, note TEXT NOT NULL, date DATE);',errorHandler); } );
errorHandler是這樣的:
function errorHandler(transaction, error){ alert('Error was: '+ error.message +'(Code:'+ error.code +')'); var fatal_error = true; if(fatal_error){ return true; } return false; }
error.message 是一段錯誤描述,error.code 是錯誤代碼 (詳情)
再看看如果從db中檢索出數據並顯示到頁面上:
db.transaction( function (transaction){ transaction.executeSql("SELECT * from notes;",[],dataHandler, errorHandler); } ); function dataHandler(transaction, results){ var string = ""; for (var i = 0; i" + row['titel'] + " "; } var listConts = $('listCont'); listConts.innerHTML = string; }
可以看出,基本上和php之類後端語言操作大同小異。
更多代碼可查看示例程序,不再一一羅列。
完成了數據的本地存儲,就要將文件存儲也搞定。為了實現文件的本地存儲,html5搞了一個叫 manifest 的文件,這個文件就是一個緩存清單,把需要緩存在客戶端的文件告訴浏覽器。manifest是一個mimetype為 text/cache-manifest 的 純文本文件。注意,這點很重要。
下面是一個manifest文件的例子:
NETWORK, CACHE, FALLBACK 都是可選的。
manifest文件必須以 CACHE MANIFEST 開頭
其後需要下載並緩存的文件使用相對或絕對路徑皆可,每個資源一行。
NETWORK段表明一些在線資源所在的域,所有這個域下的資源都不會被緩存,即使客戶端處於離線狀態,也會嘗試去請求基於這些域的資源。
CACHE段還不是很明白
FALLBACK段下面每行都包含兩部分內容,用空格分隔。後半部分是當前半部分路徑不能訪問時的備選路徑(很拗),如上圖就是,如果demoimages目錄不能訪問時,嘗試訪問images目錄。
manifest文件介紹就到這裡,下面創建我們自己的manifest文件:
我們只需要緩存兩個文件即可,nbStyle.css 和 nbScript.js。還有index.html 本身,由於manifest文件會默認緩存引用自己的文件,所以index.html 不能在緩存列表中寫出來:
CACHE MANIFEST # version: 2010-01-20 22:30 nbStyle.css nbScript.js
就是這麼簡單了,我們將他保存為 notebook.manifest 文件,並和其它文件一起放在根目錄。
最後一個問題,如果將notebook.manifest的mimetype標識為 text/cache-manifest 類型呢?我知道有兩種方法:
1. 在站點根目錄建立 .htaccess 文件,在其中聲明.manifest 的mimetype ,這個需要修改下服務器的配置文件,我沒有嘗試成功。
2. php環境在apache目錄尋找一個為 “mime.types” 的配置文件,在其最後添加一行:
text/cache-manifest manifest
然後在index.html文件引用它:
搞定了這些東西,你就可以嘗試用webkit訪問你的應用,然後離線,再嘗試使用它,程序應該也可以照常運行。
至此,html5的離線存儲基本介紹完了,下面附上打包的代碼,代碼本身沒有什麼難度,只是我寫的太爛了:
代碼下載
其實還遠沒有完,緩存下來的文件如果被更新了怎麼辦呢?如何通知客戶端更新緩存其實也有api,慢慢的再探索吧。非常期待與大家探討html5相關的問題。