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 3C
Ajax技术的核心
1. 异步交互,取代传统的请求/响应
2. 是在客户端处理用户的事件,它的事件模型是位于客户端的
其它特性
1. 更cool的效果
常见问题
1. 不支持浏览器后退历史
2. 不能建立页面书签
著名应用
1. Google Maps
2. Google Suggest
测试驱动开发
TDD JsUnit
Selenium
XMLHttpRequest XHR
XMLHttpRequest的标准操作
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来分配函数。