2.2 Web编程基础
基于B/S架构开发Web应用程序,可以选择.NET、Java等服务端技术体系,以及Web Service技术、动态网页技术(ASP.NET、JSP、PHP等)、RIA技术(JavaScript、Flex等)。在此,本书主要对HTML+CSS+JavaScript方式的Web前端开发进行讲解,是目前Web前端开发的主流方式,积累了众多的用户与资源。
JavaScript的出现使得信息和用户之间不再仅仅是一种显示与浏览的关系,实现了一种实时的、动态的、交互式的表达能力。JavaScript是一种解释性脚本语言(代码不需要预编译),在用户访问时由客户端浏览器(如IE、Firefox等)解释执行。JavaScript主要用来向HTML页面添加交互行为,是一种广泛用于客户端Web开发的脚本语言,学习JavaScript的主要目的也是为了Web开发。
基于JavaScript的Web开发,即HTML+CSS+JavaScript的Web客户端开发方式,主要分为以下几种应用模式:
(1)纯客户端模式:应用HTML+CSS+JavaScript等客户端技术进行Web系统开发,可结合基于REST的Web Service,实现数据访问或其他业务功能。
(2)综合开发模式:将Web客户端开发与Web服务器端开发结合,即客户端使用HTML+CSS+JavaScript等技术,服务器端采用.NET、J2EE等开发框架,支持基于SOAP或REST的Web Service调用。
(3)混合开发模式:以基于JavaScript的Web开发为主体,可结合Flex、Silverlight等开发方式,便于大型应用系统的集成,满足各种应用需求。
图2-6 基于JavaScript的Web系统基本架构
基于JavaScript的Web开发,不管选用哪种开发模式,其开发的Web系统基本架构如图2-6所示。客户端采用HTML、CSS、JavaScript等,呈现网页页面与实现UI效果,并通过UI行为向服务器端发送请求;服务器端使用Web服务,或者结合.NET、J2EE等开发框架通过后台应用程序与数据服务器通信请求数据。
Web前端开发的核心是HTML+CSS+JavaScript。Web前端从概念上划分为相对独立的三个层次:结构、表现和行为,在物理层面上分别对应HTML、CSS、JavaScript三种不同的的文件格式,各司其职。HTML负责定义网页的结构与内容,CSS负责内容的表现方式,JavaScript负责网页关于动态的行为反应。由此可见,HTML、CSS主要负责页面的表现;JavaScript主要负责UI行为,即页面交互、框架交互、数据的交互、表单验证等,可以动态操作所有对象。JavaScript脚本可以直接嵌入HTML页面,也可以写成单独的js文件引用,其中后者有利于结构和行为的分离。因此,本质上三者也构成一个MVC框架,即HTML作为信息模型(Model)、CSS控制样式(View)、JavaScript负责调度数据和实现某种展现逻辑(Controller)。而基于JavaScript的Web前端开发,关键是JavaScript与HTML、CSS的灵活应用。
Web前端三要素的结合,提供给Web开发者巨大的创作空间,能够实现令人惊喜的页面视觉与交互效果。如今网络上也有众多开源框架与插件,Web开发可以充分利用这些资源。关于Web前端三要素的基础学习,可以参考书籍或网络上的相关内容。其中,JavaScript由ECMAScript、DOM、BOM三个核心部分组成,其组成部分与基本内容如图2-7所示。由于JavaScript是一种基于对象和事件驱动,并具有相对安全性的客户端脚本语言,因此在学习JavaScript时需要具备一定的面向对象编程的基础。
图2-7 JavaScript组成部分与基本内容
注意:
(1)ECMAScript由ECMA(前身为欧洲计算机制造商协会,英文名称是European Computer Manufacturers Associati on)通过ECMA-262标准化的脚本程序设计语言,实际上是一种脚本在语法和语义上的标准,描述了JavaScript语言的语法和基本对象。
(2)DOM(文档对象模型)用于描述处理网页内容的方法和接口。DOM分为HTML DOM和XML DOM两种,它们分别定义了访问和操作HTML/XML文档的标准方法,并将对应的文档表现为带有元素、属性和文本的树结构(节点树),因此DOM的树结构是学习的关键。
(3)BOM(浏览器对象模型)用于描述与浏览器进行交互的方法和接口。由于BOM没有相关标准,因此每个浏览器都有自己对BOM的实现方式。BOM有窗口对象、导航对象等一些实际上已经默认的标准,但对于这些对象和其他一些对象,每个浏览器都定义了自己的属性和方式。
下面主要介绍基于Web前端三要素的Web开发的关键内容,即页面设计、交互机制与Web前后台交互。从宏观上掌握Web开发的结构与关键点,理解基于JavaScript的Web开发基本原理与方法,有助于在实践中正确、灵活地运用。
2.2.1 页面设计
Web前端开发是一项很特殊的工作,涵盖的知识面非常广,既有具体的技术,又有抽象的理念。Web前端的重点是页面的视觉与交互,需要把网站的页面更好地表现给用户,因而更注重于技巧。Web页面的设计与制作通常包括页面规划(需求)、页面设计(构思与设计)、页面实现(编码)、页面维护支持流程。
页面设计包括页面视觉设计与交互设计,重点在于页面的视觉效果与交互体验。页面设计需要遵循一定的设计规范,使得最终设计出来的页面风格一致,提高工作效率,实现以用户为中心的产品页面设计。针对页面设计,设计规范至少应该包括设计流程与设计内容的规范,而设计内容通常包括页面风格,页面框架(如框架、布局、字体、颜色等),页面交互等方面。
在进行页面设计时,一般需要根据功能需求进行分析设计,整体构思、模块化设计,由抽象转为具体。一般情况下,如果是中大型项目开发,通常会先利用主流的原型工具(如AxureRP等)进行系统原型设计(Prototype Design)。系统原型设计包括系统框架,甚至交互设计的内容,然后基于此原型设计进行修改、调整和完善,以及进一步进行视觉设计(GUI设计)等。若是简单的小系统或网站,也可以使用诸如Office工具、Adobe的Photoshop等工具进行简单的系统原型设计,如系统设计框架图、流程图等,然后进一步实现页面设计。在实践中,可根据应用需求进行低保真原型设计与高保真原型设计。开发人员与交互设计师、视觉设计师协作,基于原型设计使用HTML、CSS、JavaScript完成页面制作与实现。
提示:系统原型设计最基础的工作,就是画出站点的大体框架图并结合批注、大量的说明以及流程图等,将自己的系统原型完整而准确地表述给产品、UI、重构/开发工程师等,并通过沟通反复修改原型直至最终确认,然后进入后续的设计开发流程。
工欲善其事,必先利其器。现在是工具便捷的时代,要学会运用工具与资源,提高效率,提升质量。目前常用的网页制作工具有Adobe的网页设计“四剑客”(Photoshop、Flash、Dreamweaver、Fireworks),以及全球主流快速原型设计工具AxureRP等。另外,各种JavaScript框架和插件层出不穷,为整个前端开发领域注入了巨大的活力,可以充分利用现有的丰富资源,如jQuery、Prototype、ExtJS等。
提示:页面设计是一个看似简单,实则不易的工作。需要注重用户体验,掌握基本方法,学会相关技巧,在学习过程中扎实基础、实践校验、研究借鉴、阅读交流、培养UI感观,多实践、多看优秀作品、多思考。
2.2.2 事件机制
Web前端开发的另一关键内容就是页面交互的实现,即基于事件机制的页面动态交互、与基于Ajax引擎的前后台数据交互。在此主要讨论客户端的事件处理机制。
事件是指浏览器中发生的动作或状态变化,当与浏览器中Web页面进行某些类型的交互时,事件就发生了,即事件是用户或系统在与对象交互过程中发生的动作或状态变化。例如,用户单击网页上某个按钮、鼠标指针移动、按下键盘按键或者从服务器加载某个页面(或图像)等。基于事件机制,可以用JavaScript脚本来响应鼠标、键盘和其他情形。通过JavaScript,可以监听特定事件的发生,并规定让某些事件发生以对这些事件做出响应。事件犹如JavaScript应用跳动的心脏,Web前端开发的UI行为均基于事件机制实现,而大部分都是通过鼠标事件实现页面交互的。
事件(Event)是针对对象建立的。不同的对象可能有不同的事件类型,但大多数对象都会响应鼠标事件、键盘事件、焦点事件,这些可称为通用事件。当对象发生某个事件时,可以编制专门的程序代码,即事件处理函数(Event Handler)来处理事件从而实现某种功能。当开发的页面需要实现某一行为动作时,首先要针对行为对象定义事件(即定义一个函数)或者说为事件定义一个动作,并把事件绑定到指定的元素上,只要客户端触发了元素的事件,就会执行定义好的事件处理函数。只有将事件处理函数与对象的事件关联起来,浏览器脚本引擎才可以触发这个事件处理程序,否则按默认方式处理。
Web前端的事件处理机制就是标准的事件驱动机制,W3C制定的DOM标准支持两种事件模型,即捕获型事件和冒泡型事件,但捕获型事件先发生。目前除了IE浏览器,其他主流的Firefox、Opera、Chrome等浏览器都支持标准的DOM事件处理模型;IE浏览器仍然使用自己专有的事件模型(冒泡型),因此在Web开发中使用事件时需要注意兼容性问题。简单来说,Web前端设计的任何UI交互行为都是基于事件机制实现的,主要包括事件定义(即定义事件处理函数)、事件注册(即与元素绑定,添加事件监听器)。
W3C的DOM标准与IE自定义规范的事件注册方法各不相同。
1.DOM标准的事件监听器
在支持DOM标准事件监听器的浏览器中,每个支持事件的对象都可以使用addEventListener方法来进行事件注册,使用removeEventListener方法来移除事件注册,既支持注册冒泡型事件处理,又支持捕获型事件处理。
function addEventListener(string eventFlag, function eventFunc, [bool useCapture=false])
参数说明:eventFlag为事件名称(如click、mouseover等); eventFunc为绑定到事件中执行的动作(定义的事件处理函数); useCapture表明是在事件传递过程中的捕获阶段还是在冒泡阶段调用addEventListener方法,默认值为true(捕获阶段调用),通常设为false(冒泡阶段调用)。
2.IE自定义规范的事件监听器
在IE浏览器中,每个元素和Window对象都有两个方法:attachEvent方法和detachEvent方法。通过attachEvent方法来进行事件注册,通过detachEvent方法来移除事件注册。
function attachEvent(string eventFlag, function eventFunc)
参数说明:eventFlag为事件名称(要加上on,如onclick、onmouseover等); eventFunc为绑定到事件中执行的动作,即定义的事件处理函数。
另外,使用JavaScript的事件委托(Event Delegation)技术可以避免对特定的每个子节点添加事件监听器,事件监听器仅需添加在父节点上即可。
提示:基于JavaScript进行Web前端开发,由于浏览器的事件规则不同,使得遵循DOM标准的浏览器与IE自定义规范的浏览器之间存在兼容性问题,因此在具体实现时要分别处理,确保Web页面在各浏览器上兼容。jQuery框架对js事件进行了很好的封装,应用方便,而且跨浏览器使用,因而业界越来越倾向于使用jQuery框架。
2.2.3 前后台数据交互
事件机制实现了Web页面的动态数据交互,那么在Web开发中JavaScript是如何实现前台与后台数据交互的呢?目前主流的实现方式为基于Ajax引擎,采用XMLHTTP组件的XMLHttpRequest对象实现。Ajax引擎可以实现前台与后台数据的异步交互,并且可保证实时的、局部刷新。
基于Ajax引擎的Web浏览器与后台服务器的异步交互原理如图2-8所示,Ajax引擎特别适合Web浏览器调用后台服务器进行数据交互的应用场景。
图2-8 基于Ajax引擎的Web浏览器与后台服务器的异步交互原理
在图2-8中,Ajax引擎在后台服务器和Web前端之间充当了一个缓冲器的角色。XMLHttpRequest是Ajax引擎的核心机制,可以在Web前端使用JavaScript向后台服务器提出请求并处理响应,而不阻塞用户,从而达到无须刷新的效果。在Web开发中,Ajax引擎提供了很方便的交互式用户体验模式。
Ajax引擎并非一种新的技术,而是几种原有技术的结合体,主要由下列技术组合而成:
● 使用CSS和XHTML来表示;
● 使用DOM模型进行数据交互和动态显示;
● 使用XMLHttpRequest和后台服务器进行异步通信;
● 使用JavaScript绑定元素和调用函数。
提示:除了XMLHttpRequest对象,Ajax引擎的其他技术都是基于Web标准的,并且已经得到了广泛使用。虽然XMLHttpRequest目前还没有被W3C所采纳,但是已经是一个事实上的标准,目前几乎所有的主流浏览器都支持它,并且W3C已经开始了相关的标准化工作。
简单来说,Ajax引擎通过XMLHttpRequest对象向后台服务器发送请求,从后台服务器获得数据,然后用JavaScript处理结果,以及进行DOM更新页面。这其中最关键的一步就是从后台服务器获得数据,可以通过XMLHttpRequest来理解整个过程和基本原理。
下面通过XMLHttpRequest来分析Ajax引擎的工作原理,主要包括三个部分:
(1)创建一个XMLHttpRequest对象。不同的浏览器创建XMLHttpRequest对象的方法是有差异的。IE浏览器使用ActiveXObject,而其他浏览器使用名为XMLHttpRequest的JavaScript内建对象。其中,IE7及以上版本也提供XMLHttpRequest对象,也会继续支持ActiveX对象XMLHTTP,解决了基于Ajax引擎的浏览器兼容性问题。
(2)Web前端向后台服务器发送请求。创建对象后,使用XMLHttpRequest对象的open()和send()方法将请求发送到后台服务器。XMLHttpRequest属性的简要说明如表2-1所示,XMLHttpRequest方法的简要说明如表2-2所示。
表2-1 XMLHttpRequest的属性说明
表2-2 XMLHttpRequest的参数说明
(3)Web前端处理后台服务器返回信息。通过XMLHttpRequest对象的方法发送请求后,通过Onreadystatechange事件处理函数判断当前状态,当readyState属性为200时,可通过JavaScript处理请求返回信息responseText。
例如,一个简单的Ajax请求代码如程序代码2-1所示。
程序代码2-1 Ajax请求代码
var url=″ajaxServer.aspx″; //要请求的后台服务端地址(后台页面) //var url=″WebService.asmx/HelloWorld? msg=test″; //要请求的服务地址(Web服务) var http_request; //请求对象 //(1)创建XMLHttpRequest对象 if(window.XMLHttpRequest)//非IE浏览器及IE7(7.0及以上版本),用XmlHttpRequest对象创建 { http_requ est=new XMLHttpRequest(); } else if(window.ActiveXObject)//IE(6.0及以下版本)浏览器用ActiveXObject对象创建,如果浏览器禁 用了ActiveX,可能会失败 { http_requ est=new ActiveXObject(″Microsoft.XMLHttp″); } //(2)向后台服务器发送请求 if(http_request)//成功创建XmlHttpRequest { http_requ est.open(″GET″, url, true);//与后台服务器建立连接 http_requ est.Onreadystatechange=callback;//指定回调函数 http_requ est.send(null);//发送请求 } //(3)Web前端处理后台服务器返回的信息 function callback()//回调函数,对后台服务器的响应处理,监视response状态 { if(http_r equest.readystate==4)//请求状态为4表示成功 { if(http _request.status==200)//HTTP状态为200表示成功 { Dispaly(); //所有状态成功,处理请求返回的信息responseText } else //HTTP返回状态失败 { alert(″后台服务返回状态″ + http_request.statusText); } } else //请求状态还没有成功,页面等待 { document .getElementById(″myTime″).innerHTML =″数据加载中……″; } }
由此可见,XMLHttpRequest完全用来向后台服务器发送请求,处理后台服务器端和Web前端通信的问题。这是整个Ajax引擎实现的关键。Ajax引擎无非是两个过程,即发出请求和响应请求,完全是客户端技术。Ajax引擎的基本原理和流程可以简单为:把后台服务器看成一个数据接口,它返回的是一个纯文本流(即此文本流可以是XML、HTML,也可以是JavaScript代码,或者只是一个字符串);当XMLHttpRequest向后台服务器请求这个页面时,后台服务器将文本的结果写入页面,这跟普通的Web开发流程是一样的,不同的是,客户端在异步获取这个结果后并不是直接显示在页面上的,而是先由JavaScript来处理,然后显示在页面上。至于现在流行的很多Ajax控件,如magicajax等,可以返回DataSet等其他数据类型,这只是将整个过程封装后的结果,本质上并没有什么太大的区别。
目前,很多JavaScript框架均对Ajax引擎的请求做了封装,提供兼容且更为简便的接口或方法,使得发送请求以及处理返回结果更加简单。因此,在基于已有框架(如jQuery)封装Ajax引擎后进行Web前后台数据交互是非常简便的。
例如,使用基于jQuery框架的Ajax引擎向后台服务器发送请求示例见程序代码2-2。jQuery.ajax()可以处理复杂的逻辑,基于jQuery.ajax()封装的请求方法更加简单方便,如jQuery.get()、jQuery.post()等。
程序代码2-2 基于jQuery框架的Ajax引擎向后台服务器发送请求示例
$.ajax({ type:″POST″, //请求的方式(POST或GET) conten tType:″application/json″,//当发送信息至后台服务器时内容编码类型 url:″http: //localhost/MyService/Service1.asmx/GetAge″, //请求地址,此为服务接口 da ta:″{name:′″+name+″′}″, //发送到后台服务器的数据,此为参数名(与服务接口参数一致) dataty pe:′json′,//预期后台服务器返回的数据类型 suc cess:function(result){//请求成功后调用的回调函数 //处理返回的结果信息,略 } });
通过Ajax引擎可以解决前后台数据的异步交互的通信问题,也可以使用其他方法进行前后台的数据交互。例如,结合ASP.NET的Web开发,可以通过下列方法实现前后台的数据交互:
方法一:通过Web前端控件的AutopostBack属性、Button控件等实现表单提交。
方法二:通过Web Service来实现,即后台服务器通过标识System.Web.Services.WebMethod声明public和static的方法,Web前端的ScriptManager控件通过PageMethods方法调用后台服务器定义的方法。
方法三:通过<%=methodname()%>和<%#methodname()%>来实现,其中methodname()为后台服务器定义的方法。
方法四:通过隐藏域的方式实现(如隐藏调用服务端的按钮)。
基于JavaScript的Web开发方式非常灵活,深得用户喜爱。随着HTML5、CSS3的推出,以及各种JavaScript的开源插件的应用,该开发方式必将充分发挥其优势,为Web开发与应用推波助澜。