JavaScript大杂烩12 - 理解Ajax
AJAX缘由
再次谈起这个话题,我深深的记得就在前几年,AJAX被炒的如火如荼,就好像不懂AJAX,就不会Web开发一样。要理解AJAX为什么会出现,就要先了解Web开发面临的问题。
我们先来回忆一下Web页面的申请过程,这个咱们在第一篇中就介绍过了:Web页面开发就是在无连接和无状态的HTTP协议上管理页面的状态。每次申请页面的时候,服务器都会返回完整的HTML文本(当然还有其他的文本文件),浏览器就负责解析这个文本并在浏览器中显示。
在这个过程中,不管当前页面的内容是不是都变化了,服务器都会重新给浏览器重发一份,这个操作对于原本就比较脆弱的网络来说,实在是比较耗时,比较低效,虽然时至今日,这种方式还是很多网站的工作模式,但是还有有很多玩家开始思考如何去优化这个过程。在编程语言的发展过程中,异步是解决用户响应问题的不二法宝,所以异步的申请与局部更新的方案就产生了,这个就是AJAX。
问题的本质 - 数据交互技术
在详细总结Ajax的实践之前,我们先来深入的分析一下问题的核心。
任何的软件程序基本上都可以分为界面(UI),逻辑,数据3个部分,Web程序也不例外,在Web程序中,JavaScript承担了完成逻辑功能的任务,也就是和后台数据打交道的任务,不管是用户输入,还是获取数据,最终都表现为使用JavaScript完成与服务器的交互,这样的操作说白了就是前端界面与后端数据之间的数据交互问题。
数据交互的方式基本上也就是两种方式:同步和异步,前者会等待数据操作结束后继续执行下面的程序,后者不会等待数据操作完成,而是先执行下面的程序,在数据操作完成后再通过回调函数完成需要执行的一些工作。
而在执行数据交互的过程中,前后端也可以采取不同的联系方式:持续连接和按需连接,前者前后端一直保持连接,后者前后端只在需要的时候连接一下。
对于传统的桌面程序,由于前端与后端共存与一台机器上,所以访问比较方便,通常采用持续连接和同步访问的方式,而对于一些大数据量的操作才采用异步访问的方式(提高界面的可响应性)。
对于Web程序而言,由于前后端通常不在一台机器上,而且最初网络环境并不是太好,所以最初采用的是按需连接(申请页面的时候建立连接)和同步的方式(数据接收完毕后更新整个页面)。但是随着Web程序需求(功能性和非功能性需求)的不断提高,网络软硬件技术的不断发展,数据访问方式就理所当然的出现了异步的方式和局部更新,这就是AJAX技术。而随着HTML5技术的逐渐发展,持续连接也成为了一种可能,这就是WebSocket技术,这个在前面的HTML5系列文章中已经总结过了。
从上面的数据交互技术发展的核心脉络中我们可以更清楚的理解AJAX所处的历史地位和积极意义,下面我们就详细的看一下AJAX技术。
AJAX本质
AJAX = Asynchronous JavaScript and XML (异步的 JavaScript 和 XML)
AJAX就是在客户端申请页面时,在不重新加载整个页面的情况下,只对网页的局部进行更新的技术。使用了AJAX后,浏览器与服务器只会进行少量数据交换,这样页面的执行效率就会大幅提升。
AJAX实现的核心有两点:
1. 异步申请数据
2. 响应数据,更新局部页面
更新页面比较简单,前面DOM部分已经总结过常见的CRUD(创建,检索,更新,删除)操作了。那个剩下的的就是如何异步的申请和响应服务端的数据了,这个是通过AJAX的核心对象XMLHttpRequest来完成的。
总的来说,XMLHttpRequest对象很简单,下面来看个简单的例子:
<html> <head> <script type="text/javascript"> var xmlhttp; function loadXMLDoc(url) { xmlhttp = null; // 1. 创建XMLHttpRequest对象 if (window.XMLHttpRequest){ // 适用于浏览器IE7, Firefox, Opera, Chrome等 xmlhttp = new XMLHttpRequest(); } else if (window.ActiveXObject) { // 适用于浏览器 IE6, IE5 xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); } if (xmlhttp != null) { // 2. 挂接响应函数/回调函数 xmlhttp.onreadystatechange = stateChange; // 3. 设置申请方法 xmlhttp.open("GET",url,true); // 4. 发送申请 xmlhttp.send(); } else { alert("你的浏览器不支持XMLHTTP"); } } function stateChange() { // readyState = 4(loaded)并且status = 200(OK)代表申请数据成功 if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { // 获取响应的状态,返回的数据(XML格式) document.getElementById(‘A1‘).innerHTML = xmlhttp.status; document.getElementById(‘A2‘).innerHTML = xmlhttp.statusText; document.getElementById(‘A3‘).innerHTML = xmlhttp.responseText; } else { alert("获取XML时出错:" + xmlhttp.statusText); } } </script> </head> <body> <h2>使用HttpRequest对象</h2> <p><b>状态:</b> <span id="A1"></span> </p> <p><b>状态文本:</b> <span id="A2"></span> </p> <p><b>返回的数据:</b> <br /><span id="A3"></span> </p> <button onclick="loadXMLDoc(‘/example/xmle/note.xml‘)">获取XML</button> </body> </html>
直接运行这个例子是不行的,需要自己配置个服务器,这个例子来源于W3C,地址:http://www.w3school.com.cn/tiy/t.asp?f=ajax_httprequest_js。我只不过是加了一下注释,下面就是例子的一些说明。
1. 创建XMLHttpRequest对象
兼容性问题注意一下即可。
2. 向服务器发送请求
申请时我们使用了XMLHttpRequest对象的open()和send()方法。
open方法的第一个参数指定了请求的方式是GET或者是POST。与POST相比,GET更简单也更快,并且在大部分情况下都能用。
然而,在以下情况中,则需要使用POST请求:
1).无法使用缓存文件(更新服务器上的文件或数据库)
2).向服务器发送大量数据(POST没有数据尺寸限制)
3).发送包含未知字符的用户输入时,POST比GET更稳定也更可靠(其实还是考虑数据尺寸的限制问题)
其实说白了POST主要用于携带数据更新服务器然后返回。
open方法的第二个参数是申请的数据url,这个没什么好说的。
open方法的第三个参数是指定申请时异步(true)还是同步(false),这个其实不用考虑,估计没什么人使用同步方式。如果有些兄弟想试验一下同步的方式的话,也可以,不过响应的函数就不用挂到onreadystatechange上了,而是直接在send方法后面写上更新HTML的代码即可。
send方法发送请求,这个方法可以携带一个字符串作为参数,这个参数存储了发送给服务器的数据,简单的申请都不用给服务器发送数据,所以用法都很简单:
xmlhttp.open("POST","demo_post.asp",true); xmlhttp.send();
如果要像HTML表单那样POST数据的话,一般还要设置HTTP头,所以复杂一点的POST申请的代码大概像是这样:
xmlhttp.open("POST","ajax_test.asp",true); xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded"); xmlhttp.send("fname=Bill&lname=Gates");
这其实是更新服务器数据的操作。
3. 响应服务器端的数据
这个响应函数对于同步的申请来说很简单,直接把代码写到send方法的后面就可以了。异步申请的话要挂接到onreadystatechange事件上。
在回调函数中,我们首先需要判断服务器的处理状态,这就是通过判断例子中的readyState和status来实现的。只有readyState等于4并且status等于200的时候才表明服务器正确的返回了申请的数据,这个时候我们通过responseText或者responseXML获取到字符串格式或者XML格式的数据,然后解析处理就行了。
再论JSON与XML
在AJAX中,名字中的异步XML确实是相当惊艳,在回调函数中,直接可以使用responseXML访问XML格式的内容。不过鉴于在JavaScript中解析XML实在有点不是太方便(感兴趣的同学百度一把就知道了),至少是比解析JSON要麻烦一点,所以就像在前面我们讨论的那样:WEB开发中,JSON是王道。虽然XML是AJAX内置的一种方式,而且现实世界中确实也存在很多构建在XML或者SOAP(一种轻量的、简单的、基于XML的协议)之上的服务方式,但是除了这些必须要使用XML的服务外,使用JSON确实能带来不少的方便。
REST思想
每次看到介绍AJAX的文章,我总能在第一时间想到REST架构。
REST是英文Representational State Transfer的缩写,中文翻译为“表述性状态转移”。这个又是当前炙手可热的一个概念。这种思想的核心就是使用单一的URI标示符去标识服务器上的任何的资源,客户端使用URI去对资源进行CRUD操作。这种想法与AJAX的做法配合起来(基于REST的Web服务及基于 Ajax的客户端)可以说是十分融洽。关于REST思想,后面会专门总结它,感兴趣的同学可以先看看这个链接中的例子:http://www.ibm.com/developerworks/cn/webservices/ws-restajax/。
单页面的思想
单页面就是只有一个页面的Web程序,所有的操作都在同一个页面中完成,所有的数据交互都通过AJAX或者WebSocket完成,使用这些程序的感觉就如同使用桌面程序一样。单页面程序开发也是近年来比较火的一种开发方式,很多的公司都针对这种方式开发了相应的类库,比如谷歌的AngularJS,AJAX是构建单页面程序的核心技术之一。
单页面技术与REST模式并不是万能的,它们与AJAX紧密相关,但是又有很多的实际问题没有解决,所以大多时候,大家还是习惯把它们与别的技术,例如MVC结合起来使用。
参考资料:
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。