AJAX 技术入门详解

前言:Ajax 是当今 Web 应用程序开发过程中必不可少的一种技术,使用它可以通过异步处理的方式极大的提高用户体验,这篇文章将以简单易懂的方式介绍 AJAX 技术。

AJAX 技术简介

AJAX 即 “Asynchronous Javascript And XML”(异步 JavaScript 和 XML),音译为 “阿贾克斯”,是指一种创建交互式网页应用的网页开发技术。AJAX 通过在后台服务器进行少量的数据交换,实现对网页的异步刷新,即可以在不重新加载整个网页的情况下,对网页的局部进行更新。 Ajax 不是一个新的技术,事实上,它是一些旧有的成熟的技术以一种全新的更加强大的方式整合在一起 Ajax 的关键技术:

  • 使用 XHTML (HTML) 和 CSS 构建标准化的展示层
  • 使用 DOM 进行动态显示和交互
  • 使用 XML 和 XSLT 进行数据交换和操纵
  • 使用 XMLHttpRequest 异步获取数据
  • 使用 JavaScript 将所有元素绑定在一起

传统 Web 应用的同步处理方式

在传统的 Web 应用中,如果我们需要更新网页内容,必须重新加载整个页面,传统 Web 应用同步处理方式模型图如下:

我们可以看到,在传统的 Web 应用模型下,客户机 (浏览器或者本地机器上运行的代码)向服务器发出请求。该请求是同步的,客户机等待服务器的响应。当客户机等待的时候,会用某种形式通知您正在处理:

  • 沙漏(特别是 Windows 上)
  • 旋转皮球(通常在 Mac 机器上)
  • 应用程序基本上冻结了,然后过一段时间光标变化了

这正是传统 Web 应用程序让人感到笨拙或缓慢的原因:缺乏真正的交互性。 按下按钮时,应用程序实际上变得不能使用,直到刚刚触发的请求得到响应。如果请求需要大量服务器处理,那么等待的时间可能很长。这对用户体验是非常不友好的。

AJAX 应用的异步处理方式

Ajax 应用通过在用户和服务器之间引入一个媒介(Ajax engine)来异步发送请求,消除了传统的发送请求-等待-发送请求-等待的特性,极大的提高了用户体验。 Ajax 应用的异步处理方式模型图如下:

我们在图中可以看到,当用户在浏览器中进行一定的操作(比如点击按钮)请求更新网页内容,浏览器将请求交由 AJAX 处理,AJAX 引擎收到将请求提交给服务器,此时浏览器端无需刷新当前页面,待服务器处理完成请求后,将响应传给 AJAX 引擎,由 AJAX 来更新网页的部分内容。 这样的处理在浏览器端用户完全无需等待,完全由 AJAX 来完成整个处理。这种处理方式就是异步处理。

传统 Web 应用与 Ajax 应用的比较

废话不多说,直接看图:

创建 AJAX 核心对象

想要使用 AJAX 技术必然逃不掉 AJAX 引擎,其实说起引擎可能觉得这个概念有点过于庞大,其实在 AJAX 中,这个引擎不过就是一个对象!对,你没有看错,只是一个对象而已!这个对象就是 XMLHttpRequest。 XMLHttpRequest(简称 XHR)是一个 JavaScript 对象。这个对象产生于浏览器中,它是 AJAX 的核心。 在不同的浏览器中创建这个对象的方法不同,其实主要的原因当然来自万恶的 IE,没办法,毕竟 IE 拥有着庞大的用户群,我们在开发过程中不得不考虑兼容性问题。 那么为了解决兼容性问题,通常创建 XHR 对象的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
function ajaxFunction()
{
var xmlHttp;

try
{
// Firefox, Opera 8.0+, Safari,IE7及以上版本
xmlHttp=new XMLHttpRequest();
}
catch (e)
{
// Internet Explorer
try
{
xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");//IE较新版本
}
catch (e)
{

try
{
xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");//IE较老版本
}
catch (e)
{
alert("您的浏览器不支持AJAX!");
return false;
}
}
}
}

注意不要被这些花括号迷住了眼睛,下面分别介绍每一步:增加 try/catch 块:

  • 尝试创建 XMLHttpRequest 对象
  • 如果失败,先尝试使用较新版本的 Microsoft 浏览器创建 Microsoft 兼容的对象(Msxml2.XMLHTTP),如果失败(尝试使用较老版本的 Microsoft 浏览器创建 Microsoft 兼容的对象(Microsoft.XMLHTTP)

如果全部失败,则使用 JavaScript 警告通知用户出现了问题并返回 false。

XMLHttpRequest 常用方法及属性

onreadystatechange 属性

该属性存有处理服务器响应的函数。下面的代码定义了一个空的函数并赋值给 onreadystatechange 属性:

1
2
3
4
xmlHttp.onreadystatechange=function()
{
// 我们需要在这里写一些代码
}

readyState 属性

readyState 属性存有服务器响应的状态信息。每当 readyState 改变时,onreadystatechange 函数就会被执行。 这是 readyState 属性可能的值: AJAX - XMLHttpRequest 对象

状态 描述
0 请求未初始化(在调用 open () 之前)
1 请求已提出(调用 send () 之前)
2 请求已发送(这里通常可以从响应得到内容头部)
3 请求处理中(响应中通常有部分数据可用,但是服务器还没有完成响应)
4 请求已完成(可以访问服务器响应并使用它)

我们要向这个 onreadystatechange 函数添加一条 If 语句,来测试我们的响应是否已完成(意味着可获得数据):

1
2
3
4
5
6
7
xmlHttp.onreadystatechange=function()
{
if(xmlHttp.readyState==4)
{
// 从服务器的response获得数据
}
}

responseText 属性

可以通过 responseText 属性来取回由服务器返回的数据。

1
2
3
4
5
6
7
8
xmlHttp.onreadystatechange=function()
{
if(xmlHttp.readyState==4)
{
//例如将某一元素内的HTML代码更换为服务器发送的响应字符串
document.getElementById("某一元素id").innerHTML = xmlHttp.responseText</code>;
}
}

open () 函数

使用 XMLHttpRequest 对象的 open () 方法来建立请求。该方法有五个参数:

  • request-type:发送请求的类型。典型的值是 GET 或 POST,但也可以发送 HEAD 请求
  • url:要连接的 URL
  • asynch:如果希望使用异步连接则为 true,否则为 false。该参数是可选的,默认为 true
  • username:如果需要身份验证,则可以在此指定用户名。该可选参数没有默认值
  • password:如果需要身份验证,则可以在此指定口令。该可选参数没有默认值

通常使用其中的前三个参数。事实上,即使需要异步连接,通常指定第三个参数为 “true”,这样更容易理解。

send () 函数

一旦请求用 open () 配置好之后,就可以使用 send () 方法发送请求了,send () 方法只有一个参数,就是要发送的内容。通常在 open () 方法中已经通过 url 设置好了参数内容,因此一般 send 方法中的参数传入 null 即可。 open () 和 send () 函数的具体使用方法将通过后文中的一个简单实例来进行说明。

实例:通过邮编自动获取城市名称

前端页面

网页内容如下图所示:

当用户在邮编文本框中输入邮编时,则城市文本框内容自动改变为对应城市,我们知道,在传统 web 应用程序中如果要更新网站内容必须重新加载页面,而本实例要求只是更改城市文本框的内容,因此 AJAX 的异步处理方式最适合本实例的要求。 首先我们先准备一个 HTML 表单页面,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!DOCTYPE html>
<html>
<head>
<title>AJAX实例-通过邮政编码获取城市名称</title>
<meta charset="UTF-8"/>
<meta name="content-type" content="text/html; charset=UTF-8">
<script type="text/javascript">
</script>
</head>
<body>
邮编:
<input type="text" id="text_zipcode" name="zipcode" />
<br /> <br />
城市:
<input type="text" id="text_city" name="city" />
</body>
</html>

这个页面很简单,body 中只有两个 input 文本框标签。

AJAX 代码

下面我们来编写 AJAX 代码,通常实现一个 AJAX 功能需要四个简单的步骤:

  1. 创建 XMLHttpRequest 对象;
  2. 通过 open () 函数建立连接;
  3. 设置 onreadystatechange 属性并编写回调(callback)函数;
  4. 发送请求 send (null);

那么我们按照上面的几个步骤逐步实现: 首先我们需要创建 XHR 对象,该步骤上文已经详细介绍,在此不在赘述; 然后通过 open () 函数建立连接:open () 函数在上文中我们已经知道其可以传入 5 个参数,但实际开发中通常只需要传入三个参数即可,分别是:

  • request-type:请求类型。通常有 get 和 post 两种,在本例中由于我们只需要传递一个参数,且该参数无需加密,因此我们采用 get 方式即可,get 与 post 请求方式的区别请自行查阅相关资料;
  • url:请求链接地址及参数;
  • asynch:连接方式,分为异步连接和同步连接。当值为 true 时为异步连接,当 false 时为同步连接,默认值为 true。通常我们使用异步连接方式。

那么在本例中,open 函数的代码书写如下:

1
xhr.open("get", "zipcode.do?zipcode="+$("text_zipcode").value, true);

在代码中,我们使用 get 方式建立与 zipcode.do 建立连接并传递 zipcode 参数。 接下来我们需要书写回调函数并赋值给 onreadystatechanged 属性,这个回调函数的意义是当 ajax 的 readyState 属性发生改变时所执行的函数,通常在这个函数中我们只关心服务器处理完成 ajax 的请求后并返回响应时我们需要做的操作,因此我们需要在这个函数中加入一个 if 判断,判断是否 readyState 是否为 4,代码如下:

1
2
3
4
5
6
7
8
9
10
xhr.onreadystatechange = function(){
// 判断ajax状态码(4为成功接受服务端响应)
if (xhr.readyState == 4) {
// 判断响应状态码(200即正确响应)
if (xhr.status == 200) {
// 更新页面部分内容
$("text_city").value = xhr.responseText;
}
}
}

最后我们书写发送请求代码:send (null); 那么根据上面的步骤,我们已经实现好了 ajax 的全部代码,整合起来代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
<!DOCTYPE html>
<html>
<head>
<title>AJAX实例-通过邮政编码获取城市名称</title>
<meta charset="UTF-8" />
<meta name="content-type" content="text/html; charset=UTF-8">
<script type="text/javascript">
window.onload = function() {
$("text_zipcode").onkeyup = function() {
// 1、获取XHR对象
var xhr = createXHR();
// 判断是否成功获取XHR对象
if (xhr != false) {
// 2、建立连接
xhr.open("get", "zipcode.do?zipcode="+$("text_zipcode").value, true);
// 3、设置回调函数
xhr.onreadystatechange = function(){
// 判断ajax状态码(4为成功接受服务端响应)
if (xhr.readyState == 4) {
// 判断响应状态码(200即正确响应)
if (xhr.status == 200) {
// 更新页面部分内容
$("text_city").value = xhr.responseText;
}
}
}
// 4、发送请求
xhr.send(null);
}
};
};

function createXHR() {
var xmlHttp = false;
try {
// Firefox, Opera 8.0+, Safari,IE7及以上版本
xmlHttp = new XMLHttpRequest();
} catch (e) {
// Internet Explorer
try {
xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");//IE较新版本
} catch (e) {

try {
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");//IE较老版本
} catch (e) {
alert("您的浏览器不支持AJAX!");
xmlHttp = false;
}
}
}
return xmlHttp;
}

function $(id) {
return document.getElementById(id);
};
</script>
</head>
<body>
邮编:
<input type="text" id="text_zipcode" name="zipcode" />
<br /> <br />
城市:
<input type="text" id="text_city" name="city" />
</body>
</html>

 

后端代码

现在我们已经写好整个前端页面并实现 ajax,我们来看一下后端代码示例,由于本篇文章主要介绍 AJAX,因此后端实现方法不做过多解释,实现语言为 Java,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
package cn.javacodes.servlet;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ZipcodeServlet extends HttpServlet {

private static final long serialVersionUID = 1L;

private Map<String, String> map = new HashMap<String, String>();

public void init() {
map.put("150000", "哈尔滨");
map.put("110000", "北京");
}

public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {

response.setContentType("text/html");
response.setCharacterEncoding("UTF-8");
PrintWriter out = response.getWriter();
String zipcode = request.getParameter("zipcode");
if (map.containsKey(zipcode)) {
out.println(map.get(zipcode));
}
out.flush();
out.close();

}

public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {

doGet(request, response);
}

}

总结

Ajax 应用的开发确实有些繁琐,实际上,现在有很多成熟稳定的 Ajax 工具葙(例如 JQuery)封装了以上诸多细节,使得 Ajax 编程更加容易。但是如果不知道应用程序在做什么,就很难发现其中的问题。XMLHttpRequest 对象是 Ajax 应用的核心,必须非常熟悉。 Ajax 应用的基本流程:

  • 创建 XMLHttpRequest 对象
  • 从 Web 表单中获取需要的数据
  • 设置要连接的 URL
  • 建立到服务器的连接
  • 设置服务器在完成后要运行的回调函数
  • 发送请求

至于如何使用 AJAX 操作 XML、JSON 等,我会在以后的文章中在做讨论。