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结合起来使用。
参考资料:
JavaScript大杂烩12 - 理解Ajax的更多相关文章
- JavaScript大杂烩11 - 理解事件驱动
前面我们回顾了前端JavaScript只干的两件事:操作BOM与操作DOM,那么什么时候去干这些事呢?答案是需要干的时候去干.那么什么时候是需要干的时候呢?答案是事件被触发的时候.这就是通常所说的“事 ...
- JavaScript大杂烩1 - 理解JavaScript的类型系统
随着硬件水平的逐渐提高,浏览器的处理能力越来越强大,本人坚信,客户端会越来越瘦,瘦到只用浏览器就够了,服务端会越来越丰满:虽然很多大型的程序,比如3D软件,客户端仍然会存在,但是未来的主流必将是浏览器 ...
- JavaScript大杂烩10 - 理解DOM
操作DOM 终于到了JavaScript最为核心的部分了,通常来说,操作DOM,为页面提供更为友好的行为是JavaScript根本目标. DOM树 - HTML结构的抽象 既然DOM是操纵HTML ...
- JavaScript大杂烩9 - 理解BOM
毫无疑问,我们学习JavaScript是为了完成特定的功能.在最初的JavaScript类型系统中,我们已经分析过JavaScript在页面开发中充当着添加逻辑的角色,而且我们知道JavaScript ...
- JavaScript大杂烩8 - 理解文本解析的"黄金搭档"
文本解析"黄金搭档" - String与RegExp对象 文本解析是任何语言中最常用的功能,JavaScript中也是一样,而正则表达式作为最常用的方式,JavaScript也同样 ...
- JavaScript大杂烩7 - 理解内置集合
JavaScript内置了很多对象,简单的类型如String,Number,Boolean (相应的"值类型"拥有相同的方法),复杂一点的如Function,Object,Arra ...
- JavaScript大杂烩6 - 理解JavaScript中的this
在JavaScript开发中,this是很常用的一个关键字,但同时也是一个很容易引入bug的一个关键字,在这里我们就专门总结一下页面中可能出现的this关键字(包括几种在其他页面文件中出现的this) ...
- JavaScript大杂烩4 - 理解JavaScript对象的继承机制
JavaScript是单根的完全面向对象的语言 JavaScript是单根的面向对象语言,它只有单一的根Object,所有的其他对象都是直接或者间接的从Object对象继承.而在JavaScript的 ...
- JavaScript大杂烩3 - 理解JavaScript对象的封装性
JavaScript是面向对象的 JavaScript是一种基于对象的语言,你遇到的所有东西,包括字符串,数字,数组,函数等等,都是对象. 面向过程还是面向对象? JavaScript同时兼有的面向过 ...
随机推荐
- Linux下解压.tar.xz格式文件的方法
前言 对于xz这个压缩相信很多人陌生,但xz是绝大数linux默认就带的一个压缩工具,xz格式比7z还要小. 今天在下载Node.js源码包的时候遇到的这种压缩格式.查了一下资料,这里进行一下记录,分 ...
- Python - 集成开发环境Pycharm的使用方法和技巧
PyCharm HomePage:PyCharm 我的Pycharm,我做主 Getting Started with PyCharm Pycharm使用技巧 Documentation & ...
- Linux学习笔记之二————Linux系统的文件和目录
一.Windows和Linux文件系统区别 1.在 windows 平台下,打开“计算机”,我们看到的是一个个的驱动器盘符: 每个驱动器都有自己的根目录结构,这样形成了多个树并列的情形,如图所示: ...
- abstract、virtual、sealed、 interface、struct 基础知识整理
abstract abstract 修饰符指示被修改内容的实现已丢失或不完整. abstract 修饰符可用于类.方法.属性.索引和事件. 在类声明中使用 abstract修饰符以指示某个类仅旨在作为 ...
- Hadoop社区版搭建
1.环境准备 1.1 硬件配置 设备名 参数 数量 6台 系统 centos6.5 内存 64G 硬盘 32T/台 CPU 16核/台 1.2 软件版本 Hadoop-2.x 下载地址 JDK1.7 ...
- 200. Orchard学习 目录
201. Orchard学习 一.基础 210. Orchard学习 二.启动 211. Orchard学习 二 1.Application_Start 212. Orchard学习 二 2.Manu ...
- Android中内容提供者ContentProvider的详解
1.什么是ContentProvider 首先,ContentProvider(内容提供者)是android中的四大组件之一,但是在一般的开发中,可能使用的比较少. ContentProvider为不 ...
- NoSuchFieldError
最近用Fresco框架加载GIF动态图片,遇到一个bug,记录下来,以供后来者少走弯路: 各种百度,最后参照Fresco官方文档,将原有的 fresco:1.3.0替换成0.12.0即: 在APP b ...
- C++ 日期 & 时间
C++ 标准库没有提供所谓的日期类型.C++ 继承了 C 语言用于日期和时间操作的结构和函数. 为了使用日期和时间相关的函数和结构,需要在 C++ 程序中引用 头文件. 有四个与时间相关的类型:clo ...
- autocomplate 学习
方法一 :[使用插件] // 联想功能 stat function cselstreet() { var name = ""; //$("#txtname"). ...