AJAX技术入门详解
自建博客地址:https://www.bytelife.net,欢迎访问! 本文为博客自动同步文章,为了更好的阅读体验,建议您移步至我的博客👇
本文作者: Jeffrey
本文链接: https://www.bytelife.net/articles/30550.html
版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
前言: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对象的代码如下:
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属性:
xmlHttp.onreadystatechange=function()
{
// 我们需要在这里写一些代码
}
readyState属性
readyState 属性存有服务器响应的状态信息。每当 readyState 改变时,onreadystatechange 函数就会被执行。 这是 readyState 属性可能的值: AJAX - XMLHttpRequest 对象
状态 | 描述 |
---|---|
0 | 请求未初始化(在调用 open() 之前) |
1 | 请求已提出(调用 send() 之前) |
2 | 请求已发送(这里通常可以从响应得到内容头部) |
3 | 请求处理中(响应中通常有部分数据可用,但是服务器还没有完成响应) |
4 | 请求已完成(可以访问服务器响应并使用它) |
我们要向这个 onreadystatechange 函数添加一条 If 语句,来测试我们的响应是否已完成(意味着可获得数据):
xmlHttp.onreadystatechange=function()
{
if(xmlHttp.readyState==4)
{
// 从服务器的response获得数据
}
}
responseText 属性
可以通过 responseText 属性来取回由服务器返回的数据。
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表单页面,代码如下:
<!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功能需要四个简单的步骤:
- 创建XMLHttpRequest对象;
- 通过open()函数建立连接;
- 设置onreadystatechange属性并编写回调(callback)函数;
- 发送请求send(null);
那么我们按照上面的几个步骤逐步实现: 首先我们需要创建XHR对象,该步骤上文已经详细介绍,在此不在赘述; 然后通过open()函数建立连接:open()函数在上文中我们已经知道其可以传入5个参数,但实际开发中通常只需要传入三个参数即可,分别是:
- request-type:请求类型。通常有get和post两种,在本例中由于我们只需要传递一个参数,且该参数无需加密,因此我们采用get方式即可,get与post请求方式的区别请自行查阅相关资料;
- url:请求链接地址及参数;
- asynch:连接方式,分为异步连接和同步连接。当值为true时为异步连接,当false时为同步连接,默认值为true。通常我们使用异步连接方式。
那么在本例中,open函数的代码书写如下:
xhr.open("get", "zipcode.do?zipcode="+$("text_zipcode").value, true);
在代码中,我们使用get方式建立与zipcode.do建立连接并传递zipcode参数。 接下来我们需要书写回调函数并赋值给onreadystatechanged属性,这个回调函数的意义是当ajax的readyState属性发生改变时所执行的函数,通常在这个函数中我们只关心服务器处理完成ajax的请求后并返回响应时我们需要做的操作,因此我们需要在这个函数中加入一个if判断,判断是否readyState是否为4,代码如下:
xhr.onreadystatechange = function(){
// 判断ajax状态码(4为成功接受服务端响应)
if (xhr.readyState == 4) {
// 判断响应状态码(200即正确响应)
if (xhr.status == 200) {
// 更新页面部分内容
$("text_city").value = xhr.responseText;
}
}
}
最后我们书写发送请求代码:send(null); 那么根据上面的步骤,我们已经实现好了ajax的全部代码,整合起来代码如下:
<!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,代码如下:
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等,我会在以后的文章中在做讨论。