1、概述

AJAX,“Asynchronous JavaScript And XML”的简称,即“异步的JavaScript和XML”。AJAX的作用在于页面中,它可以异步提交请求,避免整个刷新整个页面。

我们常见的某些网站的注册,在输入用户名之后,明明还没有点击注册按钮,可能会看到页面显示“用户名已存在”之类的字眼,就是因为在你输完用户名之后,页面已经异步将你的用户名发送到服务器进行查重,并将结果返回,在页面进行局部显示,而你悄然不知已经完成了一次请求,页面也没有刷新。

 

2、XMLHttpRequest对象

要想使用AJAX技术,那么就要用到对象XMLHttpRequest,异步请求的发送和响应的接收,都是由该对象完成的。XMLHttpRequest对象是浏览器内建对象,而我们可以通过JavaScript代码进行创建和使用:
  • xmlHttp = new XMLHttpRequest();
  • //老版本IE(IE5/IE6)xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
 
由上可知,不同的浏览器对该对象的实现也有所不同,在IE中微软使用ActiveX对象实现,而其他浏览器厂商则将其作为一个本地JavaScript对象实现。所以在使用AJAX时,考虑到浏览器兼容的问题,往往也按照以下方式判断创建:
if(window.ActiveObject) {
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
} else if (window.XMLHttpRequest) {
xmlHttp = new XMLHttpRequest();
}
5
 
1
if(window.ActiveObject) {  
2
    xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
3
} else if (window.XMLHttpRequest) {
4
    xmlHttp = new XMLHttpRequest();
5
}

2.1 属性

XMLHttpRequest对象中封装了一系列属性:
属性名     说明     备注
readyState     返回当前状态 0-4共五个值
0:“未初始化”,表已经创建XMLHttpRequest对象,但尚未初始化请求对象
1:“打开”,已调用XMLHttpRequest的open()方法,准备好发送请求
2:“发送”,已调用XMLHttpRequest的send()方法,已发送请求,尚未收到响应
3:"正在接收",已收到响应头信息,消息体还没有完全接收
4:“已加载”,响应已完全接收
status 返回当前服务器状态 状态码详见《HTTP状态消息
statusText 同status,但以文字表示 同上
onreadystatechange 事件触发器 readyState、status发生变化时会触发该项,往往指定为JS函数,如:
xmlHttpRequest.onreadystatechange = callback;
responseText 接收服务器端返回的文本 返回内容以字符串形式存在
responseXML 接收服务器响应 响应内容若以XML存在,可解析为DOM对象,如:
var message =
xmlHttp.responseXML.getElementsByTagName("message")[0].firstChild.data;

2.2 方法

XMLHttpRequest除了上述六个主要属性,还定义了一系列方法:
  • open(DOMString method, DOMString uri, boolean async, DOMString username, DOMString password)
  • send()
  • setRequestHeader(DOMString header, DOMString value)
  • getResponseHeader(DOMString header)
  • getAllResponseHeaders()
  • abort()

2.2.1 open

open(DOMString method, DOMString uri, boolean async, DOMString username, DOMString password)
  • method 指定请求方式,如GET/POST
  • uri 指定XMLHttpRequest对象请求的具体URI,绝对或相对URI均可
  • async 指定该请求是否异步,默认true
  • username/password 对于需要认证的服务器,可以提供该两项参数

open方法调用后,readyState属性将为1,并把responseText、responseXML、status、statusText属性设为初始值。open方法调用后,才能对请求头信息等进行设置。

var url = "validate?custname=" + escape(custname.value);
xmlHttp.open("GET", url, true);
2
 
1
var url = "validate?custname=" + escape(custname.value);
2
xmlHttp.open("GET", url, true);
如上述代码中,使用GET方式异步请求URL为validate的服务器资源,同时将参数custname编码后追加到URL中传递给服务器。注意,如果准备使用POST方式发送请求,需要调用setRequestHeader来设置请求头,设置Content-Type为application/x-www-form-urlencoded,表示内容以表单形式提交。

2.2.2 send

send方法用来将请求发送到服务器,其方法参数可选,如果要用send()发送POST请求并携带信息,则将信息作为参数传入。

xmlHttp.open("POST", "login", true);
xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xmlHttp.send("username="+encodeURI(username));
3
 
1
xmlHttp.open("POST", "login", true);
2
xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
3
xmlHttp.send("username="+encodeURI(username));
如上述代码将username作为信息体,使用POST方法请求URL为login的服务器资源。如果不需要传递请求参数,则使用xmlHttp.send()或xmlHttp.send(null)即可。

2.2.3 其他方法

  • setRequestHeader(DOMString header, DOMString value)
  • 用来设置请求头信息,参数分别为请求头名字和对应的值
  • 该方法必须在open之后调用,否则会发生异常

  • getResponseHeader(DOMString header)
  • 根据一个响应头的名字返回其对应的值
  • 如果响应头信息没有返回客户端,则返回null

  • getAllResponseHeaders()
  • 返回所有的响应头信息,使用键值对的形式表示名字和值

  • abort()
  • 用来暂停一个与XMLHttpRequest对象联系的HTTP请求
  • 将该对象恢复到未初始化状态

3、AJAX操作示例

现在使用AJAX,模拟用户名查重的功能,基本的思路是:
  • 用户名的输入框设置onblur事件,触发用户名校验函数validate
  • validate中,先在请求发送前调用open,然后设置请求头和事件触发器onreadystatechange,再使用send发送请求
  • onreadystatechange则对应一个函数,判断响应正确后执行操作

效果示意图:


前端,index.jsp页面:
<%@page pageEncoding="utf-8" %>
<html>
<body>
<head>
<script type="text/javascript">
var xmlHttp; //创建
function createXmlHttp() {
if(window.ActiveObject) {
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
} else if (window.XMLHttpRequest) {
xmlHttp = new XMLHttpRequest();
}
} //验证用户名查重(发送请求)
function validate(){
createXmlHttp();
var username = document.getElementById("username").value;
var url = "doServlet";
xmlHttp.open("POST", url, true);
xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xmlHttp.onreadystatechange = callback;
xmlHttp.send("username=" + username);
} //处理
function callback() {
if(xmlHttp.readyState == 4) {
if(xmlHttp.status == 200) {
var result = xmlHttp.responseXML.getElementsByTagName("result")[0].firstChild.data;
document.getElementById("message").innerHTML = result;
} else {
document.getElementById("message").innerHTML = xmlHttp.status + ":" + xmlHttp.statusText;
}
}
} </script>
</head> <h2>Hello World!</h2>
<div id="message"></div>
用户名:<input type="text" id="username" name="username" value="" onblur="validate()"><br>
密码:<input type="password" id="password" name="password" value=""><br> </body>
</html>
49
 
1
<%@page pageEncoding="utf-8" %>
2
<html>
3
<body>
4
<head>
5
    <script type="text/javascript">
6
        var xmlHttp;
7

8
        //创建
9
        function createXmlHttp() {
10
            if(window.ActiveObject) {
11
                xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
12
            } else if (window.XMLHttpRequest) {
13
                xmlHttp = new XMLHttpRequest();
14
            }
15
        }
16

17
        //验证用户名查重(发送请求)
18
        function validate(){
19
            createXmlHttp();
20
            var username = document.getElementById("username").value;
21
            var url = "doServlet";
22
            xmlHttp.open("POST", url, true);
23
            xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
24
            xmlHttp.onreadystatechange = callback;
25
            xmlHttp.send("username=" + username);
26
        }
27

28
        //处理
29
        function callback() {
30
            if(xmlHttp.readyState == 4) {
31
                if(xmlHttp.status == 200) {
32
                    var result = xmlHttp.responseXML.getElementsByTagName("result")[0].firstChild.data;
33
                    document.getElementById("message").innerHTML = result;
34
                } else {
35
                    document.getElementById("message").innerHTML = xmlHttp.status + ":" + xmlHttp.statusText;
36
                }
37
            }
38
        }
39

40
    </script>
41
</head>
42

43
<h2>Hello World!</h2>
44
<div id="message"></div>
45
用户名:<input type="text" id="username" name="username" value="" onblur="validate()"><br>
46
密码:<input type="password" id="password" name="password" value=""><br>
47

48
</body>
49
</html>

后端,MyServlet处理类,访问链接为/doServlet:
public class MyServlet extends HttpServlet {

    @Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("doGet1() running...");
} @Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("doPost() running...");
String[] usernames = {"zhangsan", "lisi", "wangwu", "zhaoliu"};
String username = request.getParameter("username");
String result = "用户名可用";
if (Arrays.asList(usernames).contains(username)) {
result = "用户名已存在";
} response.setHeader("Cache-Control", "no-cache");
response.setCharacterEncoding("UTF-8");
PrintWriter out = response.getWriter();
out.println("<?xml version=\"1.0\" encoding=\"utf-8\" ?>");
out.println("<response>");
out.println("<result>" + result + "</result>");
out.println("</response>");
out.close();
} }
x
 
1
public class MyServlet extends HttpServlet {
2

3
    @Override
4
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
5
        System.out.println("doGet1() running...");
6
    }
7

8
    @Override
9
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
10
        System.out.println("doPost() running...");
11
        String[] usernames = {"zhangsan", "lisi", "wangwu", "zhaoliu"};
12
        String username = request.getParameter("username");
13
        String result = "用户名可用";
14
        if (Arrays.asList(usernames).contains(username)) {
15
            result = "用户名已存在";
16
        }
17

18
        response.setHeader("Cache-Control", "no-cache");
19
        response.setCharacterEncoding("UTF-8");
20
        PrintWriter out = response.getWriter();
21
        out.println("<?xml version=\"1.0\" encoding=\"utf-8\" ?>");
22
        out.println("<response>");
23
        out.println("<result>" + result + "</result>");
24
        out.println("</response>");
25
        out.close();
26
    }
27

28
}

注意,我们这里的请求使用了POST,所以需要设置请求头Content-Type为application/x-www-form-urlencoded,这个值表示以表单提交。而后端我们的响应返回了xml格式的内容,所以用到了responseXML对象,它可以解析其为DOM对象方便操作。

实际上,现在更多的AJAX已经不再使用XML作为传输格式了,因为过于笨重。现在普遍使用的是JSON格式,后端书写方便,前端又能使用JS直接解析使用。


[01] AJAX的更多相关文章

  1. Ajax全解

    jQuery确实是一个挺好的轻量级的JS框架,能帮助我们快速的开发JS应用,并在一定程度上改变了我们写JavaScript代码的习惯. 我们先来看一些简单的方法,这些方法都是对jQuery.ajax( ...

  2. Jquery Ajax时 error处理 之 parsererror

    Jquery Ajax时 error处理 之 parsererror     01 $.ajax({ 02         type: "POST", 03         con ...

  3. 关于Ajax的type为post提交方式出现请求失效问题

    最近碰到这样一个问题,原本一个ajax异步提交数据之前是很好的,很多系统都延用了均未出现任何问题.最近这个版本却出现ajax方式post数据不到后台程序,让我折腾了好几天.起初的ajax是这样写的: ...

  4. Asp.net Ajax(ashx)

    主要实现 ajax分页功能 效果图 后台方法代码展示 /// <summary> /// WebAjax处理类 /// </summary> public class WebA ...

  5. PHP. 02®. Ajax异步处理、常见的响应状态、XMLHttpRequest对象及API、ajax的get/post方法、

    异步对象 a)创建异步对象 b)设置请求的url等参数 c)  发送请求 d)注册时间 e)在注册的事件中获取返回的内容并修改页面显示的内容 布尔类型不能直接用echo输出 常见的响应状态 Ajax概 ...

  6. 跨域的另一种解决方案CORS(CrossOrigin Resource Sharing)跨域资源共享

    在我们日常的项目开发时使用AJAX,传统的Ajax请求只能获取在同一个域名下面的资源,但是HTML5打破了这个限制,允许Ajax发起跨域的请求.浏览器是可以发起跨域请求的,比如你可以外链一个外域的图片 ...

  7. HTML笔记05------AJAX

    AJAX初探01 AJAX概念 概念:即"Asynchronous JavaScript And XML" 通过在后台与服务器进行少量数据交换,AJAX可以使网页实现异步更新.这意 ...

  8. 编程从入门到放弃(Java)

      1.Java入门篇 1.1 基础入门和面向对象 1.1.1 编程基础 [01] Java语言的基本认识 [02] 类和对象 [03] 类的结构和创建对象 [04] 包和访问权限修饰符 [05] 利 ...

  9. PDF在线预览 (flexpaper+swftools+saveaspdfandxps)

    1.使用SaveAsPDFandXPS将office文档转换成PDF http://www.microsoft.com/downloads/details.aspx?FamilyID=4d951911 ...

随机推荐

  1. 前端面试题整理——javaScript部分

    (1)typeof 和 instanceof 1.typeof 对于基本数据类型(boolean.null.undefined.number.string.symbol)来说,除了 null 都可以显 ...

  2. TFS 安装遇到的问题

    居然是是微信桌面客户端占用了8080端口,也是醉了... 1 VS链接 源码管理器 发现提示 Http 404, 发现原来是自己吧tfs 给删除了 2 重新安装tfs,过程中提示 8080 端口被占用 ...

  3. Android Color颜色代码

    常用颜色代码 <?xml version="1.0" encoding="utf-8"?> <resources> <color ...

  4. python爬虫之Beautifulsoup学习笔记

    相关内容: 什么是beautifulsoup bs4的使用 导入模块 选择使用解析器 使用标签名查找 使用find\find_all查找 使用select查找 首发时间:2018-03-02 00:1 ...

  5. [20171225]变态的windows批处理4.txt

    [20171225]变态的windows批处理4.txt --//昨天学习windows 批处理的echo &.使用它可以实现类似回车换行的功能.例子: 1.echo &.R:\> ...

  6. Fiddler查看接口响应时间

    有时候,某些接口访问过慢,我们需要测试接口查看响应时间,从而进行优化.(由于fiddler自带的没有进行响应时间的统计,所以我们需要给他添加新的规则) 首先打开Fiddler,在菜单栏上面找到Rule ...

  7. Azure 标准与高级托管磁盘存储的相互转换

    托管磁盘提供两种存储选项:高级(基于 SSD)和标准(基于 HDD). 它允许基于性能需求在这两个选项之间轻松切换,并保障最短停机时间. 非托管磁盘不具备此功能. 但可以轻松转换为托管磁盘,以便在这两 ...

  8. python第六十三天-- 第十一周作业

    题目:基于RabbitMQ rpc实现的主机管理 需求: 可以对指定机器异步的执行多个命令例子:>>:run "df -h" --hosts 192.168.3.55 ...

  9. 3.3Python数据处理篇之Numpy系列(三)---数组的索引与切片

    目录 (一)数组的索引与切片 1.说明: 2.实例: (二)多维数组的索引与切片 1.说明: 2.实例: 目录: 1.一维数组的索引与切片 2.多维数组的索引与切片 (一)数组的索引与切片 1.说明: ...

  10. Lua 与 C 交互之UserData(4)

    lua作为脚本于要能够使用宿主语言的类型,不管是宿主基本的或者扩展的类型结构,所以Lua提供的UserData来满足扩展的需求.在Lua中使用宿主语言的类型至少要考虑到几个方面: 数据内存 生命周期 ...