相对于jQuery、YUI以及其他一些类库的AJAX封装,原生JS的AJAX显得那么的尴尬,兼容性不好,要记很多的方法属性,调用不便捷,代码臃肿…但我还是想说,原生JS才是最根本最底层的知识(虽然实际项目中我也是以jQuery AJAX为主,为什么?高效!),求木之长者,必固其根本。
什么是AJAX? 它的优点劣势是什么?
Asynchronous JavaScript and XML(异步JavaScript和XML),是一种创建交互式网页应用的网页开发技术。简单的说它是多种技术的组合,目的就是让前台的数据交互变得更快捷,不用刷新页面就可以完成数据的更新。关于它的概念,止于此。想了解更多,请前往:http://zh.wikipedia.org/zh/AJAX
优点很明显,利于用户体验,不会打断用户的操作,在不刷新页面的情况下更新内容,减小服务器压力也是它很硬性的一个优点;而缺点,除了倍受追捧的SEO问题,安全问题、前进后退(这个虽然可以用其他方法解决,但AJAX本身的机制还是没变)、破坏程序的异常机制以及对新兴手持设备支持不完美的问题都是它现存的一些缺点。人无完人,AJAX也是如此,我们并不能因为它有缺点而摒弃它。
什么地方需要AJAX?
其实这是一个太宽泛的问题,各人各项目都有不同的用处,依我的经验与理解,AJAX应该用于小面积更新数据而不希望整个页面刷新的情况下使用。比如对用户名或者注册邮箱等数据判断、内容选项卡内容、弹出的登录注册窗口以及用户提交信息后的反馈信息等等。
实践出真知!
崇尚思考加实践,我坚信这是深入任何一门技术的必备法宝。下面,我就以一个常用的验证用户是否使用的实例,浅尝辄止的讲解一下基础的AJAX。查看样例演示
验证用户名这种数据判断,不用多说了,会一点点前端的人都知道是必须的。最传统的模式可能是输入信息,然后用户点提交后alert出一个窗口,告诉用户XXX用户名已被注册,请重新输入!我讨厌极丑的alert框!我想大多用户也是一样。此时,AJAX就可以华丽登场了。当用户输入完名字后,在表单外任何地方点一下(失去焦点),AJAX就迅速把用户输入的信息反馈到服务器端判断,并迅速返回一个信息告知用户输入的昵称是否可用。如此,我们需要一个前台的输入表单,代码如下:
1 | < form action = "#" method = "post" name = "iform" > |
2 | < p >< label for = "nickname" >用户名:</ label > |
3 | < input name = "nickname" id = "nickname" placeholder = "在这里输入用户名" type = "text" >< span id = "tips" ></ span ></ p > |
另外,我们还需要一个判断输入昵称是否存在的后端页面(本文以PHP为例,这部分不用细究):
02 | if (isset( $_GET [ 'entryname' ])){ |
03 | $entryname = $_GET [ 'entryname' ]; |
05 | $entryname = 'DATA NULL' ; |
07 | $sql =sprintf( "select * from i_test_ajax where nickname='%s'" , $entryname ); |
08 | $res = $iajax ->query( $sql ); |
11 | if (( $res ->num_rows)>0){ |
如此,万事俱备,只欠东风,剩下的就交给AJAX来处理了。
XMLHttpRequest,不得不提的一个对象,AJAX最核心也是最底层的对象。可悲哀的是,它是W3C的一个标准,但微软IE一直很自我(微软IE)。怎么办?当然是用一个方法和谐掉它们。微软IE支持ActiveXObject(‘Microsoft.XMLHTTP’)对象,这样就简单了:
03 | if (window.ActiveXObject){ |
04 | XHR= new ActiveXObject( 'Microsoft.XMLHTTP' ); |
05 | } else if (window.XMLHttpRequest){ |
06 | XHR= new XMLHttpRequest(); |
兼容的XMLHttpRequest对象实现了,接下来写一个简单的onblur事件,即当输入值后,表单失去焦点后开始判断并迅速回馈一个信息到前台。代码如下:
02 | document.forms[ 'iform' ].nickname.onblur = function (){ |
04 | var val=document.forms[ 'iform' ].nickname.value; |
06 | if (!/^[a-zA-Z0-9_]{3,16}$/.test(val)){ |
07 | alert( '请输入3~16位由英文、数字、下划线组成的昵称!' ); |
13 | XHR.open( 'GET' , '/demo/ajax/iajax20110306_query.php?entryname=' +val, true ); |
15 | XHR.onreadystatechange=returnFun; |
解释一下AJAX部分的代码。iBase.IXHR(),初始化XHR,以保证XMLHttpRequest对象的兼容。接下来,通过以GET的方式,异步发送到/demo/ajax/iajax20110306_query.php页面进行验证。有人会问什么是GET,GET是从服务器上请求数据,GET方法就是把数据参数队列加到一个URL上,值和表单是一一对应的,比如本文的entryname=val。这个概念可能属于后台程序的范畴,不在此细说。然后,我们需要用到一个onreadystatechange事件属性,这个属性是用来存储函数(或函数名),每当readyState属性改变时,就会调用该函数,即本文中的returnFun;最后,我们还要发送一个数据到服务器,send属性一般用于数据交换,而本文只是一个简单的验证判断,所以,send一个空值。
基本的判断与数据发送完成了,接下来还剩一个关键的信息获取,即returnFun。先看代码:
03 | if (XHR.readyState==1){ |
04 | iBase.Id( 'tips' ).innerHTML= 'Loding...' ; |
05 | } else if (XHR.readyState==4){ |
10 | iBase.Id( 'tips' ).innerHTML=XHR.responseText; |
此函数是用来通过判断readyState及status状态也及时反馈给用户相应的提示信息。readyState有五种状态:
0 (未初始化): (XMLHttpRequest)对象已经创建,但还没有调用open()方法;
1 (载入):已经调用open() 方法,但尚未发送请求;
2 (载入完成): 请求已经发送完成;
3 (交互):可以接收到部分响应数据;
4 (完成):已经接收到了全部数据,并且连接已经关闭。
如此一来,你应该就能明白readyState的功能,而status实际是一种辅状态判断,只是status更多是服务器方的状态判断。关于status,由于它的状态有几十种,我只列出平时常用的几种:
100——客户必须继续发出请求
101——客户要求服务器根据请求转换HTTP协议版本
200——成功
201——提示知道新文件的URL
300——请求的资源可在多处得到
301——删除请求数据
404——没有发现文件、查询或URl
500——服务器产生内部错误
至此,一个简单的AJAX验证实例就完成了:查看样例演示
关于AJAX的基础介绍与实例就这么多,关键还是在于自己的实践与思考。其实这其中涉及知识并不复杂,若有后端程序的基础,学起AJAX会更加容易,关键是要想明白其中的逻辑关系。有兴趣的话,可以自己写一个不刷新页面加载新内容的AJAX,或者研究一下jQuery中关于AJAX的封装。