<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
Ajax Foundation Ajax基礎
什麼是DHTML = HTML+CSS+DOM+JAVASCRIPT
XML衍生構建WEB UI 標記:
1. XUL Xml用戶界面語言(XML User Interface Language)由Mozilla推出。
2. XAML 可擴展應用標記語言(eXtensible Application Markup Language)基於.Net平臺
3. MXML 最佳體驗標記語言(Maximum eXperience Markup Language) Adobe Flex平臺
4. XAMJ是一個XML UI並且與Java語言緊密的結合.它以類似於JNLP的方式來進行部署不需要編譯或與應用程序捆綁在一起。
5. XFORMS W<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />3C
Ajax技術的核心
1. 異步交互,取代傳統的請求/響應
2. 是在客戶端處理用戶的事件,它的事件模型是位於客戶端的
其它特性
1. 更cool的效果
常見問題
1. 不支持瀏覽器後退歷史
2. 不能建立頁面書籤
著名應用
1. Google Maps
2. Google Suggest
測試驅動開發
TDD JsUnit
Selenium
XMLHttpRequest XHR
XMLHttpRequest的標準操作
<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" />
XMLHttpRequest的標準屬性
Var xmlHttp;
Function createXMLHttpRequest() {
If(window.ActiveObject) {
xmlHttp = new ActiveXObject('Microsoft.XMLHTTP');
}else if(window. XMLHttpRequest) {
xmlHttp = new XMLHttpRequest()
}
}
Ajax標準過程
Post與Get的區別
一般情況下:
Get:
1. 將所有參數附加到url中
2. 用於讀取數據,儘量不用來提交數據
3. 提交數據時,會服務器會限制url長度
Post:
1. 寫入數據,數據在請求體中發送,不會限制大小
2. 需要指定“content-type=application/x-www-form-urlencoded”
Http方法還包括:Head,Delete
請示返回內容:xml,json,html,script
通過gateway方式實現跨域訪問,見例子。
AJAX相關工具
JSDoc :一個類似javadoc的工具。
FireFox firebug
DOM Inspector
FireFox Web Developer
http://validator.w3.org/check?verbose=1
www.jsLint.com javascript語法檢查
javascript壓縮工具:
http://hometown.aol.de/_ht_a/memtronic/MemTronic_CruncherCompressor_v09g.html
prototype 實現繼承機制
私有變量:在對象或方法體內用var申明的變量
對象繼承:通過複製屬性可以實現繼承功能
function createInheritance(parent, child) {
var property;
for(property in parent) {
if(!child[property]) {
child[property] = parent[property];
child.property = parent[property];
}
}
}
測試驅動開發
www.edwardh.com/jsunit/
selenium.thoughtworks.com/index.html
Greasemonkey firefox的擴展,允許用戶向任何頁面中動態添加javascript,改變其行爲。
Taconite 開發框架
瀏覽器兼容,見例子。
Ajax In Action Ajax實戰
JavaScript是一種弱類型,通用的,解釋型的腳本語言。
RIA ,富客戶端,高交互性
Ajax原則
1. 瀏覽器中的是應用而不是內容 :它可將部分業務邏輯從服務器移到瀏覽器端。
2. 服務器交付的是數據,而不是內容:整體上消耗的帶寬比傳統Web應用低一點。
3. 讓交互變得流暢而連續。大部分對服務器端的請求,是隱式的而不是顯式的。
4. 有紀律的嚴肅編程。代碼是巨大的、複雜的、組織良好,從架構的角度,需要認真對待。
Ajax 關鍵元素
1. javascript 允許應用與瀏覽器進行交互。
2. CSS 爲頁面元素提供一種可重用的可視化樣式定義方法。
3. DOM 一組可能使用javascript可以操作的可編程對象,展現web面頁結構。
4. XMLHttpRequest 提供瀏覽器與後臺通信方式。
工作方式:
Ajax 重構
1.目的
a.不增加功能的情況,使代碼更加清晰。創建小的、易讀的、易修改的、來解決特定問題的功能。
b.發掘出程序中通用的、可用的解決問題的方案――設計模式。
注:Javascript語言優點是特別靈活,同時對一般的水平的程序員來說,它缺少必要的安全保障。
設計模式使用原則:設計模式只不是工具,只應該出現在確實有用的地方。如果過度使用,將導致“分析癱瘓”,導致遲遲不能進行實施。
Ajax 常用設計模式
1. 處理瀏覽器不一致使用:Façade、和Adapter適配器模式
2. Observer,客戶端事件處理
3. Command 模式do/undo
4. 單例模式,Singleton
正常情況:
Function LoginModel() {
This.mode=MODE _SSO;
}
LoginModel.prototype.setMode=function() {
}
然後使用一個全局變量作爲僞單例:
LoginModel.instance = new LoginModel();
問題:
方法二:不使用prototype,直接手工創建對象:
var LoginModel = new Object();
LoginModel.mode=MODE_SSO;
LoginModel.setMode = function() {
}
上面方法的一個變種爲:
var LoginModel = {
mode : MODE_SSO,
setMode:function() {
}
}
UI開發經久不衰的、萬金油似的設計模式:MVC
Ajax 應用構架設計 MVC
l 狀態內部表示是模型。Ajax UI組件通常實現爲Javascript對象。
l 顯示在屏幕上、由DOM節點組件的UI組件,在Ajax用戶界面中是視圖。視圖有兩個責任:它必須爲用戶提供一個可視的界面,以便觸發事件用來與控制器對話;它也需要在模型改變時做出響應,更新自己,通常需要再次與控制器進行通信。
l 將兩者關聯起來的內部代碼是控制器。事件處理函數代碼(按鈕)也是控制器,但不是這個視圖和模型的控制器。
例子:ch04-musical_dyn_keys.html
綁定事件的方法:
1. 不正確的寫法:mydiv.οnclick=showMsg():調用方法
2. 正確的寫法:mydiv.οnclick=showMsg,指向方法的引用
Javascript組件
function Button(value,domEl){
this.domEl = domEl;
this.value = value;
this.domEl.buttonObj = this;
this.domEl.onclick = this.clickHandler;
}
Button.prototype.clickHandler=function() {
var buttonObj = this.buttonObj;
var value= (buttonObj && buttonObj.value) ? buttonObj.value: “unknown value”;
alert(value);
}
問題:V能直接訪問M嗎?
Observer模式例子:ch04-mousemat_observer_pattern.html
Model一般爲數據:由服務器端提供的xml或json
常用腳本庫:
1. prototype
2. scriptaculous,建立於prototype之上的效果庫
3. rico,同上
4. jQuery
5. dojo
服務器端角色:
數據交換:
1. 僅限於客戶端的:在客戶端js中,不存在與服務器端數據交互
2. 以內容爲中心的:返回一段html代碼,客戶端用innerHtml
3. 以腳本爲中心的:返回服務器端生成的一段script,eval+鉤子回調
上邊兩種方法的問題:
a.層間緊密耦合,
b.script上下方衝突
4. 以數據爲中心的:胖客戶端,UI與應用邏輯解耦。Xml 或 json,視圖可以通過xslt
缺點:數據的解析與展現全部交給了客戶端,大量的js,客戶端非常複雜,需要進行良好的設計與大量可用組件。
在實際應用中,三種方法可以相互補充。
向服務器端發送數據:
1. html form表單
2. XMLHttpRequest+命令隊列,可以顯著減少請求數量
CommandQueue方法:同一個請求,處理多個命令,對命令進行配置,並分配一個id,然後回寫之後,根據Id更相應視圖。
專業級的AJAX
一、用戶體驗:
1. 可用代碼的關鍵特徵
a) 做正確的事:開發高質量的應用。響應性、健壯性、一致性、簡單性。在代碼中實踐
2. 可重用的通知框架:在頁面中提示消息的通用功能。Message,Display
3. 在原處突出顯示更新過的數據
二、Ajax安全性
1. javascript的安全模型:
a) sandbox
b) 來源服務器
c) 子域問題:document.domain=’alisoft.com’使可訪問所有子域的script
解決方案:
a) 使用代理服務器
2. 遠程webservice
a) IE的web service 安全區域
b) Mozilla:PrivilegeManager
try{
if (this.secure && netscape && netscape.security.PrivilegeManager.enablePrivilege) {
netscape.security.PrivilegeManager.enablePrivilege('UniversalBrowserRead');
}
}catch (err){}
REST
3. 保護internet上的用戶數據
a) Https,保護數據通道,防止中間人修改數據
b) 加密:在http上使用javascript密碼數據,公鑰與私鑰:MD5
4. 保護ajax數據流
a) 設計時請求或數據粗度問題:細粒度會爆露更多的攻擊點,粗粒度的又影響用戶的可用性。需要在架構設計時根據業務情況進行平衡。
b) 過濾http請求:如使用filter,進行必要的邏輯及安全性檢查
c) 使用http會話,即session:少傳一些參數
d) 使用加密的Http頭部信息
三、性能
運行的速度快慢與消耗資源的多少。優化需要考慮方法,以及帶來的回報。
1. 執行速度
a) 不同的算法,性能差別非常大
b) 將dom節點附加到文檔樹上時,該節點被立即被呈現。如果有很多節點需要添加dom中,最好全部構建好之後,再添加一次添加到dom中。注這種優化方法,在ie7.0中已經不明顯,且好像更差。
c) 變量儘量少用點號”.”,因爲會引來內存中多次查找。
2. 內存使用量。
垃圾回收機制:通過判斷程序是否能夠通過變量之間形成的引用網絡到達該變量。當確定沒有引用時,加上可回收標記,並且在下一次清理中回收該變量。
產生內存泄漏的方法:使用完變量,忘記解除引用。
(1) 當它引用其它已刪除的對象時,將會消耗多少內存?如果對象很多時,內存將無法估量
(2) 額外內存消耗將會保持多長時間
3. Ajax的特殊考慮因素。
MVC。模型通常由可以自己來定義和實例化的純JavaScript對象組成。視圖主要由DOM節點組成,DOM節點就是瀏覽器暴露給Javascript環境的原生對象。控制器將兩者粘合在一起。
a) 打破循環引用:DOM與JavaScript對象之間的互相引用。
b) 移除DOM元素
a. 隱藏移除:稍後我們是否需要重用該DOM節點。Style.display=’none’
b. 分離移除:removeChild
c) 創建規則:Creaate Always還是Create If Not Exists
d) IE的特別注意:將相應的引用置爲null
4. 考慮性能的設計
a) 測量內存的使用量。通過任務管理器
b) Process Explorer
c) Drip,很好的分析及引用,內存使用量工具
不同的設計內存差別很大
Ajax實例
1. 動態雙組合功能
2. 輸入前提示
3. 增強的ajax web 門戶
4. 使用ajax 創建獨立的應用
5. 使用xslt創建動態應用
附:
1. JavaScript對象實質本質是:由字段和函數組成,本質上是一個關聯數組。
2. 瀏覽器讀取並解釋執行文本流。
3. Json:對象和數組,沒有其它類型。
4. 構造函數,類,原型
a) this,運行時確定爲對象的實例。
5. 原型的繼承-通過組合實現繼承
6. javascript對象反映:if(obj1.somePropertiy):當值爲false,o,null測試都爲:false。最好使用typeof(obj1.somePropertiy) != “undefined”,進行判斷。
7. 方法和函數:call,apply。
a) Fuction.call(obj,x,y,z):第一個參數是函數上下文使用的對象,後面的爲參數。
b) Function.apply(obj,paramters) 第一個參數是函數上下文使用的對象,第二個參數數組,它更靈活,可以不限制參數個數。
c) 在方法體內可以通過arguments,取得傳入的參數情況。
8. 通過名稱引用模型:objs[this.id]=’abcd’
9. 閉包:捆綁了所有需要的資源的Function對象,隱式創建,沒有 辦法得到其句柄,它與本地變更綁在一起,不能被垃圾回收器回收。如果再在閉包中引用DOM節點,可能會造成嚴重的內存泄漏。
例:
function Robot() {
var createTime = new Date();
this.getAge = function() {
var now = new Date();
var age = now –createTime;
return age;
}
}
建議:閉包有他們的用處,但是最好把他們看作是一種高級的技術。如果有替代方法,就避免使用閉包。可以使用prototype來分配函數。