`

读书笔记: JavaWeb从入门到精通 第13章: Ajax 技术

阅读更多

通过阅读本章, 你可以:

  • 了解 Ajax 开发模式与传统开发模式的比较

  • 掌握如何使用 XMLHttpRequest 对象

  • 通过 Ajax 向服务器发送请求

  • 通过 Ajax 处理服务器的响应

  • 通过 Ajax 实现检测用户名是否唯一

  • 进行 Ajax 重构

  • 通过 Ajax 实现实时显示公告信息

  • 通过 Ajax 实现无刷新的级联下拉列表

  • 通过 Ajax 实现上传文件时显示进度条

13.1 当下谁在用 Ajax

13.1.1 百度搜索提示

13.1.2 淘宝新会员免费注册

13.1.3 明日科技编程词典服务网

 

13.2 Ajax 开发模式与传统开发模式的比较

对于每个用户的请求, 在传统的 Web应用 模式中, 将生成一次HTTP请求, 而在 Ajax 应用 开发模式中, 将变成对 Ajax 引擎的一次 JavaScript 调用. 在  Ajax 应用开发模式中 通过 JavaScript 实现在不刷新整个页面的情况下, 对部分数据进行更新, 从而降低了网络流量, 给用户带来更好的体验.

 

13.3 Ajax 使用的技术

Ajax (Asynchronous JavaScript and XML) 是 XMLHttpRequest 对象 和 JavaScript, XML, CSS, DOM 等多种技术的组合. 其中, 只有 XMLHttpRequest 对象是新技术, 其他的均为已有技术. 

XMLHttpRequest 对象

它是一个具有应用程序接口的 Javascript 对象, 能够使用 超文本传输协议(HTTP) 连接服务器, 是微软公司为了满足开发者的需要, 与1999年在 IE5.0 浏览器中率先推出的.

XML

XML 是 eXtensible Markup Language (可扩展的标记语言) 的缩写, 它提供了用于描述结构化数据的格式, 适用于不同应用程序间的数据交换, 而且这种交换不以预先定义的一组数据结构为前提, 增强了可扩展性. XMLHttpRequest 对象与服务器交换的数据通常采用XML格式.

[例13.1] (略)

注意: 在XML文档中, 必须有一个根元素,  所有其他的元素必须嵌入到根元素中.

JavaScript

Ajax 就是利用 JavaScript 将 DOM, XHTML (或 HTML), XML 以及 CSS 等技术综合起来, 并控制它们的行为的. 因为要开发一个复杂高效的 Ajax 应用程序, 就必须对 JavaScript 有深入的了解.

CSS

CSS 是 Cascading Style Sheet ( 层叠样式表) 的缩写, 用于(增强) 控制网页样式并允许将样式信息与网页内容分离的一种标记性语言. 

DOM

DOM 是文档对象模型的简称, 是表示文本(如HTML文档)和访问, 操作构成文档的各种元素(如 HTML标记和文本串) 的应用程序接口. W3C 定义了 标准的 文档对象模型, 它以树形结构表示 HTML 和 XML 文档, 并且定义了 遍历树 和 添加, 修改, 查找树的节点的方法和属性. 在 Ajax 应用中, 通过 JavaScript 操作 DOM, 可以达到在不刷新页面的情况下实时修改用户界面的目的.

 

13.4 使用 XMLHttpRequest 对象

13.4.1 初始化 XMLHttpRequest 对象

IE 浏览器

IE 浏览器把 XMLHttpRequest 实例化为一个 ActiveX 对象. 具体方法如下:

 

1
2
3
var http_request = new ActiveXObject("Msxml2.XMLHTTP");
// or
var http_request = new ActiveXObject("Microsoft.XMLHTTP");

在上面的语法中, Msxml2.XMLHTTP 和 Microsoft.XMLHTTP 是针对 IE 浏览器 的不同版本而进行设置的, 目前比较常用的是这两种.

非IE浏览器

非IE浏览器(如 Chrome, FireFox, Opera, Mozzila, Safari) 把 XMLHttpRequest 对象实例化为一个本地 JavaScript 对象. 具体方法如下:

1
var http_request = new XMLHttpRequest();

为了提高程序的兼容性, 可以创建一个跨浏览器的 XMLHttpRequest 对象. 

1
2
3
4
5
6
7
8
9
10
11
if(window.XMLHttpRequest){    // non-IE browser
    http_request = new XMLHttpRequest();
else if(window.ActiveXObject){    // IE browser
    try{
        http_request = new ActiveXObject("Msxml2.XMLHTTP");
    catch(e){
        try{
            http_request = new ActiveXObject("Microsoft.XMLHTTP");
        }catch(e){}
    }
}

在上面的代码中, 调用 window.ActiveXObject 将返回一个对象, 或是 null. 在 if 语句中, 会把返回值看作是 true 或 false.

13.4.2 XMLHttpRequest 对象的常用方法

open方法

open 方法用于设置进行异步请求目标的 URL, 请求方法以及其他参数. 其具体语法如下:

open("method", "URL", [,asyncFlag,[,"username"[,"password"]]])

参数说明:

method: 指定请求的类型, 一般为 GET 或 POST.

URL: 指定请求地址, 可以是绝对地址或相对地址, 并且可以传递查询字符串.

asyncFlag: 为可选参数, 异步请求为 true, 同步请求为 false, 默认情况下为 true.

username: 为可选参数, 用于指定请求用户名, 没有时可省略.

password: 为可选参数, 用户指定请求密码, 没有时可省略.

[例13.2] 设置异步请求目标为 register.jsp, 请求方法为 GET, 请求方式为异步的代码如下:

 

1
http_request.open("GET""register.jsp"true);

send(content) 方法

send() 方法用于向服务器发送请求. 如果请求声明为异步, 该方法立即返回, 否则将等到接受到响应为止.

content: 用于指定发送的数据, 可以是 DOM 对象的实例, 输入流 或 字符串. 如果没有参数需要传递, 可以设置为null.

[例13.3] 向服务器发送一个不包含任何参数的请求, 可以使用下面的代码:

1
http_request.send(null);

setRequestHeader()方法, 用于为请求的 HTTP头 设置值. 

setRequestHeader("header", "value");

header: 用于指定 HTTP头

value: 用于为指定的 HTTP头 设置值.

注意: setReqeustHeader() 方法必须在调用 open() 方法之后才能调用.

[例13.4] 在发送POST请求时, 需要设置 Content-Type 请求头的值为 "application/x-www-form-urlencoded", 这是就可以通过 setRequestHeader() 方法进行设置. 具体代码如下:

1
http_request.setRequestHeader("Content-Type""application/x-www-form-urlencoded");

abort() 方法用于停止或放弃当前异步请求. 其语法格式如下:

abort()

getResponseHeader()方法, 用于以字符串形式返回指定的 HTTP头 信息.  其语法格式如下:

getResponseHeader("headerLabel")

参数说明:

headerLabel: 用于指定 HTTP头, 包括 Server, Content-Type 和 Date 等.

[例13.5] 要获取 HTTP头 Content-Type 的值, 可以使用以下代码:

1
http_request.getResponseHeader("Content-Type");

上面的代码将获取到类似以下内容:

text/html;charset=GB18030

 

getAllResponseHeaders() 方法, 用于以字符串形式返回完整的 HTTP头 信息, 其中包括 Server, Date, Content-Type 和 Content-Length.

[例13.6] 使用下面的代码调用 getAllResponseHeaders() 方法, 将弹出如图13.6 所示的对话框(省略)显示完整的 HTTP 头信息.

 

13.4.3 XMLHttpRequest 对象的常用属性

onreadystatechange 属性

onreadystatechange 属性用于指定状态改变时所触发的事件处理器. 在 Ajax 中, 每个状态改变时都会触发这个事件处理器, 通常会调用一个JavaScript 函数.

[例13.7] 指定状态改变时触发 JavaScript 函数 getResult 的代码如下:

1
http_request.onreadystatechange = getResult;

注意: 在指定所触发的事件处理器时, 所调用的 JavaScript 函数不能添加小括号以及指定参数名. 不过这里可以使用匿名函数. 例如, 要调用带参数的函数 getResult(), 可以使用下面的代码:

 

1
2
3
http_request.onreadystatechange = function(){
    getResult("添加的参数");  // 调用带参数的函数
};                            // 通过匿名函数来指定要带参数的函数

readyState 属性

 

用于获取请求的状态

表 13.1 readyState 属性的属性值及其意义

 

意义 意义
0 未初始化 3 交互中
1 正在加载 4 完成
2 已加载    

responseText 属性: 

用于获取服务器的响应, 表示为支付串.

responseXML 属性:

responseXML 属性用于获取服务器的响应, 表示为 XML. 这个对象可以解析为一个 DOM 对象.

status 属性:

用于返回服务器的 HTTP 状态码, 常用的状态码 如表13.2 所示.

表13.2 status 属性的状态码

 

意义 意义
200 表示成功 404 

文件未找

202 表示请求被接受, 但尚未成功 500 内部服务器错误
400 错误的请求    

statusText 属性

statusText 属性用于返回 HTTP 状态码对应的文本, 如 OK 或 Not Found 等.

 

13.5 与服务器通信--发送请求与处理响应

13.5.1 发送请求

无论发送GET请求还是POST请求, 都需要经过以下 4 个步骤:

(1) 初始化 XMLHttpRequest 对象. 为了提高程序的兼容性, 需要创建一个跨浏览器的 XMLHttpRequst 对象, 并且判断 XMLHttpRequest 对象的实例是否创建成功, 如果不成功, 则给予提示.

[例13.8] 发送请求.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
http_request = false;
if(window.XMLHttpRequest){ // non-IE browser
    http_request = new XMLHttpRequest();
}else if(window.ActiveXObject){ // IE browser
    try{
        http_request = new ActiveXObject("Msxml2.XMLHTTP");
    }catch(e){
        try{
            http_request = new ActiveXObject("Microsoft.XMLHTTP");
        }catch(e){}
    }
}
if(!http_request){
    alert("无法创建 XMLHttpRequest 对象实例!");
    return false;
}

(2) 为XMLHttpRequest 对象指定一个返回结果处理函数(即 回调函数), 用于对返回结果进行处理. 具体代码如下:

[例13.9] 设置回调函数.

1
http_request.onreadystatechange = getResult; //调用返回结果处理函数

注意: 使用 XMLHttpRequest 对象的 onreadystatechange 属性指定回调函数时, 不能指定要传递的参数.如果要指定传递的参数, 可以使用以下方法:

 

1
http_request.onreadystatechange = function(){ getResult(param) };

(3) 创建一个到服务器的连接. 在创建时, 需要指定发送请求的方式(即GET或POST), 以及设置是否采用异步方式发送请求.

[例13.10] 采用异步方式发送 GET 请求 的具体代码如下:

http_request.open('GET', url, true);

[例13.11] 采用异步方式发送 PSOT 请求的具体代码如下:

http_request.open('POST', url, true);

说明: 在 open() 方法中的 url 参数, 可以是一个 JSP页面的 URL 地址, 也可以是 Servlet 的映射地址.

技巧: 在指定 URL 参数时, 最好将一个时间戳追加到该 URL 参数的后面, 这样可以防止因浏览器缓存结果而不能实时得到最新的结果. 例如, 可以指定 URL参数 为以下代码:

1
String url="deal.jsp?nocache="+new Date().getTime();

(4) 向服务器发送请求. XMLHttpRequest 对象的 send() 方法 可以实现向 服务器发送请求, 该方法需要传递一个参数, 如果发送的是 GET 请求, 可以将该参数设置为null; 如果发送的是 POST 请求, 可以通过该参数指定要发送的 请求参数.

向服务器发送 GET 请求的代码如下:

1
http_request.send(null); // 向服务器发送 GET 请求

[例13.12] 向服务器发送POST请求的代码如下:

 

1
2
3
4
//需要注意的是, 在发送POST请求前,还需要设置正确的请求头
http_request.setRequestHeader("Content-Type""application/x-www-form-urlencoded");
var param="user"+form1.user.value+"&pwd="+form1.pwd.value+&email="+form1.email.value; // 组合参数
http_request.send(param); // 向服务器发送请求

13.5.2 处理服务器响应

  1. 处理字符串响应

    [例13.13] 将字符串响应显示到提示对话框中的回调函数的具体代码如下:

     

    1
    2
    3
    4
    5
    6
    7
    8
    9
    function getResult(){
        if(http_request.readyState == 4){    //判断请求状态
            if(http_request.status == 200){  //判断响应状态
                alert(http_request.responseText);
            else{
                alert("您所请求的页面有错误!");
            }
        }
    }
    如果需要将响应结果显示到页面的指定位置, 那么可以预先在页面的适当位置添加一个<div>或<span>标记, 并设置其id属性, 然后在回调函数中使用如下代码显示响应结果:

     

    1
    document.getElementById("div_result").innerHTML=http_request.responseText;
  2. 处理XML响应

[例13.14] 保存图书信息的 XML 文档. 具体代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
<?xml version="1.0" encoding="UTF-8"?>
<mr>
    <books>
        <book>
            <title>Java Web 程序开发范例宝典</title>
            <publisher>人们邮电出版社</publisher>
        </book>
        <book>
            <title>Java 范例完全自学手册</title>
            <publisher>人们邮电出版社</publisher>
        </book>
    </books>
<mr>

在回调函数中遍历图书信息的XML文档, 并将其显示到页面中的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function getResult{
    if(http_request.readyState == 4) {  //判断请求状态
        if(http_request.status == 200){ //判断响应状态
            var xmldoc = http_request.responseXML;
            var str="";
            for(i=0;i<xmldoc.getElementsByTagName("book").length;i++){
                var book=xmldoc.getElementsByTagName("book").item(i);
                str=str+" <<"+book.getElementsByTagName("title")[0].firstChild.data+">> 由 "+book.getElementsByTagName("publisher")[0].firstChild.data+" 出版<br>";
            }
            document.getElementById("book").innerHTML=str;
        }else{
            alert("您所请求的页面有错误!");
        }
    }
}
<div id="book"></div>

13.5.3 一个完整的实例 -- 检测用户名是否唯一

[例13.15]检测用户名是否唯一. (实例位置: disc\TM\sl\13\1)

(1)创建index.jsp文件, 在该文件中添加用于收集用户注册信息的表单及表单元素, 以及代表"检测用户名"按钮的图片, 并在该图片的onclick事件中调用 checkName() 函数, 检测用户名是否已被注册.

//CODE

(2) 在页面的适当位置添加用于显示提示信息的<div>标记, 并通过CSS设置该<div>标记的样式.

//CODE

(3) 编写JavaScript函数 createRequest().

//CODE

(4) 编写回调函数 getResult().

//CODE

(5) 编写JavaScript函数 checkUser(), 用于检测用户名是否为空, 当用户名不为空时, 调用 createRequest() 函数发送异步请求检测用户名是否已被注册.

//CODE

(6) 编写检测用户名是否已被注册的处理页checkUser.jsp.

//CODE

说明: 由于本实例比较简单, 这里没有从数据库中获取用户列表, 而是将用户列表保存在一个一维数组中. 在实际项目开发时, 通常情况下是从数据库中获取用户信息.

 

13.6 解决中文乱码问题

Ajax 不支持多种字符集, 其默认的字符集是 UTF-8, 所以在使用 Ajax 技术的程序中, 应及时进行编码转换, 否则程序中出现的中文字符将变成乱码.

 

13.6.1 发送请求时出现中文乱码

(1) 当接收使用GET方法提交的数据时, 要将编码转换为 GBK 或 UTF-8.

1
2
String selProvince=request.getParameter("parProvince");
selProvince=new String(selProvince.getBytes("ISO-8859-1"),"UTF-8");

(2)用于使用POST方法提交数据时, 默认的字符编码是 UTF-8, 所以当接收使用 POST 方法提交的数据时, 要将编码转换为UTF-8.

1
2
String username=request.getParameter("user");
username=new String(username.getBytes("ISO-8859-1"),"UTF-8");

13.6.2 获取服务器的响应结果时出现中文乱码

由于 Ajax 在接收 responseText 或 responseXML 的值时是按照 UTF-8 的编码格式进行解码的, 所以如果服务器端传递的数据不是UTF-8格式, 在接收 responseText 或 responseXML 的值时, 就可能产生乱码. 解决的办法是 确保从服务器端传递的数据采用 UTF-8 的编码格式.

 

13.7 Ajax 重构

13.7.1 Ajax 重构的步骤

//TODO

13.7.2 使用 Ajax 重构实现实时显示公告信息

//TODO

[例13.17] 实时显示公告信息. (实例位置: disc\TM\sl\13\2)

//CODE

13.8 Ajax 常用实例

13.8.1 级联下拉列表

[例13.18] 级联下拉列表. (实例位置: disc\TM\sl\13\3)

//TODO

13.8.2 显示进度条

[例13.19] 显示进度条. (实例位置: disc\TM\sl\13\4)

//TODO

13.9 小结

XMLHttpRequest 对象是 Ajax 的核心技术, 需要重点掌握.

如何进行 Ajax 重构需要读者重点掌握, 这在以后的项目开发中比较常用.

13.10 实践与练习

  1. 编写JSP程序, 在网页中显示实时走动的系统时钟. (disc\TM\sl\13\5)

  2. 编写JSP程序, 实时显示新闻信息. (disc\TM\sl\13\6)

  3. 编写JSP程序, 使用 Ajax 实现工具提示. (disc\TM\sl\13\7)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics