AJAX是现在一门比较流行的技术,它使客户体验上升到了一个新的高度,极大的改善了网页的呈现效果(倒如GOOGLE地图),能够进行无刷新更新页面内容。同时,由于不刷新页面使得不用去服务器上再把整个网页下载过来了,只需传送更新的数据,从而减少了带宽的占用,提高了数据传送效率。
刚开始,在我没有接触过AJAX之前,一向觉得学习新技术都不易的我见到同事们一说到AJAX便滔滔不绝,口若悬河。心中不由的有几分佩服和羡慕,同时,也激起我对AJAX学习的欲望。正巧,工作上正好需要用到这种技术,于是我开始对AJAX进行一翻全方位式的学习。学完后,回头再一看,其它AJAX也没有我原来想象的那么复杂。为了与更多想学AJAX的同事们分享学习成果,下面我详细讲述一下我学习的心得,希望或多或少能对你学习AJAX有所帮助。
(一)首先,我们明确一下AJAX的定义:
AJAX =
异步
JavaScript + XML
由上面看出学习AJAX先得有Javascript和XML的基础,我具体解释一下这个公式:
1)javascript一种比较通用的面向对象的浏览器脚本语言,要做到对页面动态效果操作自如就必需熟练掌握javascript脚本的编写,同时,要写出优秀的AJAX程序也必需有它的支持。
2)XML则主要指得是XMLHttpRequest这个对象,正是因为有了这个对象才使AJAX能够使客户端和服务端进行通信。这一点在后面我会具体说明。
3
)异步当然就是指AJAX能够进行异步传输,可能会有同事不清楚什么异步,在这里我简单打个比方说明一下。
条件:现在有张三和李四两个人
同步:张三问李四“你吃饭了没有?”,李四没有回答,张三则一直等李四回答后才进行下一次提问!
异步:张三问李四“你吃饭了没有?”,李四没有回答,张三又接着问“今天星期几?”,张三如果接到李四对第一个问题的回答,就做出反馈。换句话说张三的问题等于在排队,我就一直问你问题,你可以不回答,一旦你回答了我才反馈,至于我问多少问题这就是我的自由了!
(二)接下来我分析一下基于HTTP协议的客户端与服务端之间是怎么进行通信的和XMLHttpRequest会在里面办演什么样的角色。
1)
客户端发送
HTTP
请求
-
à
---<
网络
>--
à
--
服务器端(已启动
HTTP
包的监听)
说明:客户端通过网络对服务端进行
HTTP
请求,其实我们平时在
IE
敲一个地址后输入就是触发得这个动作。
2)
服务端响应
HTTP
请求后进行一定的处理通过网络返回
-
à
---<
网络
>--
à
--
客户端接收
说明:服务器响应
HTTP
请求后做出一定处理,然后再把信息通过网络返回给客户端。
这两步就是一个HTTP通信的简化过程,现在XMLHttpRequest对象办演的就是客户端这个角色,而这里的服务端可以是多种形式,比如WebServices,,PHP页面,aspx页面等等。
(三)在熟悉了上面的基础后,现在应该理论联系实践,下面我给大家讲两个比较具体和实用的AJAX应用的例子,一个是运用AJAX访问ASPX页面,另一个就是运用AJAX访问WebServices。
1)首先要建立两个页面,一个client.htm页,另一个ShowTime.aspx页。(为了方便在这里我就直接把JS写在HTML页面里了)
client.htm:
<
html
xmlns="http://www.w3.org/1999/xhtml" >
<
head
>
<
script
type="text/javascript">
var xmlHttp
function getTime()
{
xmlHttp=GetXmlHttpObject()
if (xmlHttp==null)
{
alert ("
您的浏览器不支持AJAX!"
);
return;
}
var url="ShowTime.aspx";
xmlHttp.onreadystatechange=stateChanged;
xmlHttp.open("GET",url,true);
xmlHttp.send(null);
}
function stateChanged()
{
if (xmlHttp.readyState==4)
{
document.getElementById("lb_time").innerHTML=xmlHttp.responseText;
}
}
function GetXmlHttpObject()
{
var xmlHttp=null;
try
{
// Firefox, Opera 8.0+, Safari
xmlHttp=new XMLHttpRequest();
}
catch (e)
{
// Internet Explorer
try
{
xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
}
catch (e)
{
xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
}
}
return xmlHttp;
}
</
script
>
</
head
>
<
body
onload="setInterval('getTime()',500)">
<span id="lb_time"></span>
</
body
>
</
html
>
ShowTime.aspx:
aspx页面很简单只需在ShowTime.aspx.cs的Page_Load函数中加一句话
Response.Write(DateTime.Now);//用来返回服务器时间
对上面的代码做一下简单的说明:
client.htm页通过AJAX来访问服务器时间,然后显示在client.htm页面中。ShowTime.aspx作用只是用来返回服务器时间,这里只是做个比较简单的例子 方便大家理解原理。如果要完成一些比较复杂的功能的话,则可以在ShowTime.aspx页面做文章。比如说,可以通过ShowTime.aspx访问数据库,AD或是其它一些网络资源,在做完一定的逻辑处理后再返回某种形式的数据给client.htm来展示。HTTP请求主要有Get和Post两种方式,例子中是用的Get方式, 如果要带参数的话就用?把参数带进来,然后在ASPX页面中就Request.QueryString取得。如果想改用POST的方式,只需把xmlHttp.open("GET",url,true);语句中的GET换成POST。
GetXmlHttpObject函数主要用来获得XMLHttpRequest对象,因为不同浏览器对XMLHttpRequest的实例化方式有点差异,所以定义一个函数,来适应不同浏览器,提高程序的可运行范围。
stateChanged
函数是在
client.htm
页面收到
ShowTime.aspx
页面返回的数据后才执行的
(
XMLHttpRequest
对象的状态发生改变时,
stateChanged()
函数就会执行。当状态变更为
4,
表示完成状态
)
,然后跟据返回的数据改变
client.htm
页面的数据。
getTime函数则是用来调用XMLHttpRequest对象,执行client.htm页面对ShowTime.aspx页面的请求。
setInterval函数的用法我就不详细说明了,网上资料很多,此处作用就是每隔500毫秒的时间运行getTime()函数。
2)刚才给出了AJAX访问aspx页面的例子,下面的例子展示AJAX怎么访问WebServices。为了更好的理解下面的例子我先做一点点有关WebServices的说明,WebServices是基于SOAP协议的,而上面的例子是通过HTTP协议来访问ASPX页面的,不知道会不会有人一下子就会认为AJAX既支持HTTP协议又支持SOAP协议,那么AJAX是跨协议的。如果你这么想的话我个人觉得对一半错一半,错的原因是你可能对SOAP协议还不是很清楚。SOAP协议是建立在HTTP协议上的,或许能用继承来说明他们之间的关系吧。SOAP协议在HTTP包的上面再加上一层封装,具体封包格式在下面的例子中你可以看到。而对一半的原因是什么意思呢?如果我换个说法,AJAX是跨基于HTTP协议的协议。我们先不管有没有必要,倘若你在HTTP协议的基础上制定出自己的协议的话,那AJAX也可以对此协议进行有效的访问,也就实现了AJAX的跨协议。呵呵,好象说得有点远了,还是赶紧写例子吧!
同第一个例子一样得有两部分,一个是client.htm客户端页面,另一个就是我们的WebServices,这次我们用WebServices中的getTimeSrv方法来返回服务器时间, 同时还给此方法加上一个strMsg参数。
client.htm:
<
html
xmlns="http://www.w3.org/1999/xhtml" >
<
head
>
<title>
无标题页</title>
<script type="text/javascript">
var xmlHttp
//WebServices
地址
var webServiceURL="http://localhost:23650/WebSite3/WebService.asmx";
function getTimeSrv(strMsg)
{
xmlHttp=GetXmlHttpObject()
if (xmlHttp==null)
{
alert ("
您的浏览器不支持AJAX!"
);
return;
}
xmlHttp.onreadystatechange=stateChanged;
xmlHttp.open("POST",webServiceURL,true);
//
填写HTTP头
xmlHttp.SetRequestHeader ("Content-Type","text/xml; charset=utf-8");
xmlHttp.SetRequestHeader ("SOAPAction","http://tempuri.org/getTimeSrv");
//
进行SOAP封装
var data;
data = '<?xml version="1.0" encoding="utf-8"?>';
data = data + '<soap:Envelope mlns:xsi=http://www.w3.org/2001/XMLSchema-instance xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">';
data = data + '<soap:Body>';
data = data + '<getTimeSrv xmlns="http://tempuri.org/">';
data = data + '<strMsg>'+strMsg+'</strMsg>';
data = data + '</getTimeSrv>';
data = data + '</soap:Body>';
data = data + '</soap:Envelope>';
xmlHttp.send(data);
//
换成setTimeout也行
setTimeout("getTimeSrv('"+strMsg+"')",500);
}
function stateChanged()
{
if (xmlHttp.readyState==4)
{
document.getElementById("lb_time").innerHTML=xmlHttp.responseText;
}
}
function GetXmlHttpObject()
{
var xmlHttp=null;
try
{
// Firefox, Opera 8.0+, Safari
xmlHttp=new XMLHttpRequest();
}
catch (e)
{
// Internet Explorer
try
{
xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
}
catch (e)
{
xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
}
}
return xmlHttp;
}
</
script
>
</
head
>
<
body
onload="getTimeSrv('
服务器时间:')">
<span id="lb_time"></span>
</
body
>
</
html
>
WebServics
中要添加的方法:
[WebMethod]
public string getTimeSrv(string strMsg)
{
return strMsg+DateTime.Now.ToString();
}
说明: 其实通过
HTTP访问WebServices跟HTTP访问ASPX主要差别就是在是否进行SOAP封包。如果想加入身份验证的话,可以在SOAP封包的时候加入SOAP头来做身份验证,第二个例子用到了setTimeout函数,而第一个函数用到的是setInterval,两个函数功能差不多,原理一样实现的方式不同罢了。平时我们写代码时可以尝试经常换换方式来实现,这样的话对提高写代码的水平和质量很有帮助!
(四)以上就是AJAX基本原理,而平时我们进行开发AJAX网站的时候可能会运用一些AJAX框架。其实这些AJAX框架已经将细节都进行了封装,这样我们使用起来会更方便。但是在框架实现不了或是实现起来比较麻烦的时候(因为框架基于多方面的考虑会对我们有很多限制),我们则有必要采用更直接的方式了,同时采用直接的方式更容易让我们了解AJAX的本质。