JavaWeb笔记之AJAX技术

一、理解AJAX

1.1 AJAX是什么?

AJAX是英文Asynchronous JavaScript and XML 的缩写,含义是异步JavaScript与XML。

1.2 AJAX主要实现什么功能

该技术主要实现客户与服务器的异步通信实现页面的部分刷新。AJAX可以在不刷新整个页面的情况下用JavaScript操作DOM以实现页面动态更新。

1.3 AJAX相关的技术

1.3.1 XML与XSL

XML(eXtendsible Markup Language):可扩展的标记语言

  • XML 指可扩展标记语言(EXtensible Markup Language)
  • XML 是一种标记语言,很类似 HTML
  • XML 的设计宗旨是传输数据,而非显示数据
  • XML 标签没有被预定义。您需要自行定义标签。
  • XML 被设计为具有自我描述性。
  • XML 是 W3C 的推荐标准
  1. 没有任何行为的 XML , XML 是不作为的。
    也许这有点难以理解,但是 XML 不会做任何事情。XML 被设计用来结构化、存储以及传输信息。

下面是 John 写给 George 的便签,存储为 XML:

<note>
<to>George</to>
<from>John</from>
<heading>Reminder</heading>
<body>Don't forget the meeting!</body>
</note>

上面的这条便签具有自我描述性。它拥有标题以及留言,同时包含了发送者和接受者的信息。

但是,这个 XML 文档仍然没有做任何事情。它仅仅是包装在 XML 标签中的纯粹的信息。我们需要编写软件或者程序,才能传送、接收和显示出这个文档。

  1. XML 仅仅是纯文本
  2. XML 不是对 HTML 的替代
    XML 是对 HTML 的补充。
    XML 不会替代 HTML,理解这一点很重要。在大多数 web 应用程 序中,XML 用于传输数据,而 HTML 用于格式化并显示数据。
    对 XML 最好的描述是:
    XML 是独立于软件和硬件的信息传输工具。

XSL(eXtendsible Stylesheet Language):可扩展的样式单语言,它是一种用来转换XML文档结构的语言。使用XSL可以从一个XML文档中提取数据,并使用该信息创建另一个XML文档。

1.3.2 XMLHttpRequest

XMLHttpRequest是浏览器中定义的对象,它是AJAX技术中的核心对象。	通过JavaScript脚本可以创建XMLHttpRequest 对象。XMLHttpRequest 对象定义了若干属性和方法,通过这些方法和属性就可以向服务器发出异步请求和处理响应结果。

二、XMLHttpRequest 对象

2.1 创建XMLHttpRequest对象

var xmlHttp;
function createXMLHttpRequest(){
	if(window.XMLHttpRequest){
	    //  IE7+, Firefox, Chrome, Opera, Safari 浏览器执行代码
		xmlHttp = new XMLHttpRequest();
	}else{
	 	// IE6, IE5 浏览器执行代码
		xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
	}
}

2.2 XMLHttpRequest 的属性

属性名说明
onreadystatechange为异步请求设置事件处理程序。每当XMLHttpRequest对象的状态改变时都会触发这个事件处理器,通常会调用一个JavaScript函数
readState该属性表示请求的状态。它可以有下面几个不同的值:0:未初始化;1:正在加载;2:已加载;3:交互中;4:完成
responseText检索服务器响应,并表示为文本
responseXML检索服务器响应,并表示为XML DOM对象
status检索服务器的HTTP状态码。如404 表示Not Found,200表示OK
statusText检索服务器的HTTP状态码的文本;
responseBody检索响应体。该属性是IE7及以后版本的window对象,但不是W3C的规范

2.3 XMLRequest 的方法

方法名说明
abort()取消当前HTTP请求
getAllResponseHeaders()返回所有的请求头。如果 readyState 属性的值不是 3或4,将返回 null。
getResponseHeader()返回指定的响应头。如果 readyState 属性的值不是 3或4,将返回 null。
open(method,url,async)规定请求的类型、URL 以及是否异步处理请求。method:请求的类型;GET 或 POST ;url:文件在服务器上的位置;async:true(异步)或 false(同步)
send()发送 HTTP 请求,使用传递给 open() 方法的参数,以及传递给该方法的可选请求体。
setRequestHeader()向一个打开但未发送的请求设置或添加一个 HTTP 请求。

2.4 一个简单的示例

simpleRequest.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Simple XMLHttpRequest</title>
    <script type="text/javascript">
        var xmlHttp;
        function createXMLHttpRequest() {
            if (window.XMLHttpRequest) {
                xmlHttp = new XMLHttpRequest();
            }
            else
            {
                xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
            }
        }

        function startRequest() {
            createXMLHttpRequest();
            xmlHttp.onreadystatechange = handleStateChange;
            xmlHttp.open("GET", "simpleResponse.xml", "true");
            xmlHttp.send(null);
        }

        function handleStateChange() {
            if (xmlHttp.readyState == 4) {
                if (xmlHttp.status == 200) {
                    alert("服务器返回:" + xmlHttp.responseText);
                }
            }
        }
    </script>
</head>
<body>
<form action="#">
    <input type="button" value="开始异步请求" onclick="startRequest();"/>
</form>
</body>
</html>

simpleResponse.xml

Hello from the server!

2.5 AJAX 的交互模式

在这里插入图片描述

  1. 客户触发事件
<input type="button" value="开始异步请求" 
    onclick="startRequest();"/>

这里,当用户点击按钮时,将触发onclick事件,程序调用startRequest()函数。

  1. 创建XMLHttpRequest 对象

在startReques()函数中调用createXMLHttpRequest()函数创建了XMLHttpRequest对象

var xmlHttp;
function createXMLHttpRequest() {
   if(window.XMLHttpRequest) {
       xmlHttp = new XMLHttpRequest();
   }
   else{
       xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
   }
}
  1. 向服务器发出请求

在向服务器发出请求之前,应该通过XMLHttpRequest 对象的 onreadystatechange 属性设置回调函数。当XMLHttpRequest 对象的内部状态改变时就会调用回调函数,因此回调函数是处理响应的地方。

function startRequest() {
	createXMLHttpRequest();
	xmlHttp.onreadystatechange = handleStateChange;
	xmlHttp.open("GET", "simpleResponse.xml", "true");//打开一个HTTP请求,请求的HTTP方法为GET,请求的资源是simpleResponse.xml,并且为异步请求
	xmlHttp.send(null);
}

接下来调用XMLHttpRequest 对象的open() 打开一个HTTP请求,在该方法中需要指定请求的HTTP方法(GET方法或者POST方法)以及请求的资源。请求的资源可以是动态资源,如Servlet、CGI脚本或者任何服务器技术等。
调用XMLHttpRequest 对象的**send()**将请求发送到指定的目标资源,send()接受一个参数,通常是一个字符串或DOM对象。这个参数作为请求体的一部分发送到目标URL。当向send()提供参数时,要确保open()中指定的HTTP方法为POST。如果使用POST方法,则需要设置XMLHttpRequest 对象的Content-Type首部,如下所示:

xmlHttp.setRequestHeader("Conetnt-Type","application/x-www-form-urllencoded");
//如果需要像 HTML 表单那样 POST 数据,请使用 setRequestHeader() 来添加 HTTP 头。

如果没有数据作为请求体的一部分发送,该参数应指定为null。

  1. 服务器处理请求并返回响应

如果请求的是静态资源,服务器将返回该资源。如果请求的是动态资源,服务器将执行动态资源,这可能需要访问数据库甚至另一个系统,然后向用户返回响应。
XMLHttpRequest对象提供两个访问服务器响应的属性。一个属性是responseText,它将响应提供一个字符串。另一个属性是responseXML,它将响应提供为一个XML对象。

//使用responseText属性来访问服务器响应
function handleStateChange() {
   if (xmlHttp.readyState == 4) {
      if (xmlHttp.status == 200) {
         alert("服务器返回:" + xmlHttp.responseText);
      }
   }
}

由于XMLHttpRequest 对象只能处理text/html类型的结果,所以如果请求的是动态资源(如Servlet),需要将Content-Type响应头设置为text/xml,另外,为了避免浏览器在本地缓存结果,需将Cache-Control响应头设置为 no-cache,如下所示:

response.setHeader("Cache-Control","no-cache");
  1. 通过回调函数处理结果

通过 回调函数可以对响应结果进行处理。在回调函数中首先应该检查XMLHttpRequest 对象的redyState 属性和status 属性的值。当readyState 属性值为4、status 属性的值为200 时表示响应完成,这时才能使用XMLHttpRequest 对象的responseText 或 response XML 检索请求结果。

//回调函数
function handleStateChange() {
   if (xmlHttp.readyState == 4) {
      if (xmlHttp.status == 200) {
         alert("服务器返回:" + xmlHttp.responseText);
      }
   }
}
  1. 更新HTML DOM 对象

客户使用新的数据更新HTML DOM 页面表示元素。JavaScript脚本可以使用DOM API 获得 HTML 的每个元素的引用。一般方法是使用document.getElementById(“userIdMessage”),这里,userIdMessage 是HTML 文档的一个元素的id属性值。有了元素的引用,JavaScript就可以修改元素的属性、修改元素的style属性或者添加、删除、修改子元素。修改元素内容的一个常用方法是设置元素的innerHTML 属性值

2.6 使用 innerHTML 属性创建动态内容

innerHTML 属性是一个简单的字符串,表示一组开始标签和结束标签之间的内容。

  • 举例:
    innerHTML.html
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>学生查询</title>
    <script type="text/javascript">
        var xmlHttp;
        function createXMLHttpRequest() {
            if (window.XMLHttpRequest) {
                xmlHttp = new XMLHttpRequest();
            }
            else {
                xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
            }
        }
        function startRequest() {
            createXMLHttpRequest();
            xmlHttp.onreadystatechange = handleStateChange;
            xmlHttp.open("GET", "innerHTML.xml", "true");
            xmlHttp.send(null);
        }
        function handleStateChange() {
            if (xmlHttp.readyState == 4) {
                if (xmlHttp.status == 200) {
                    document.getElementById("results").innerHTML = xmlHttp.responseText;
                }
            }
        }
    </script>
</head>
<body>
<form action="#">
    <input type="button" value="查询学生" onclick="startRequest();"/>
    <div id="results"></div>
</form>
</body>
</html>

innerHTML.xml

<?xml version="1.0" encoding="utf-8" standalone="no" ?>
<table border="1">
    <tbody>
        <tr><td>学号</td><td>姓名</td><td>性别</td><td>年龄</td>
        </tr>
        <tr><td>1001</td><td>张三</td><td></td><td>19</td>
        </tr>
        <tr><td>1002</td><td>李四</td><td></td><td>24</td>
        </tr>
        <tr><td>1003</td><td>王五</td><td></td><td>23</td>
        </tr>
    </tbody>
</table>

点击“查询学生按钮”,运行结果如下:
在这里插入图片描述

三、DOM 和JavaScript

3.1 DOM的概念

DOM(Document Object Model)指的是文档对象模型,它是W3C的一个规范,可以用一种独立平台和语言的方式访问和修改文档的内容和结构。DOM是面向HTML 和XML 文档的API,为文档提供了结构化表示,并定义了如何通过脚本来访问文档结构。文档中的每个元素都是DOM的一部分。在HTML页面通常使用JavaScript 脚本语言来访问DOM。
一个web页面是一个文档。这个文档可以在浏览器窗口或作为HTML源码显示出来。但上述两个情况中都是同一份文档。文档对象模型(DOM)提供了对同一份文档的另一种表现,存储和操作的方式。 DOM是web页面的完全的面向对象表述,它能够使用如 JavaScript等脚本语言进行修改。

3.2 DOM 与 JavaScript

DOM 与JavaScript 很容易混淆。DOM是面向HTML 和XML 文档的API,为文档提供了结构化表示,并定义了如何通过脚本来访问文档结构。
人们一般使用JavaScript代码,通过 **DOM 来访问文档和其中的元素。**DOM 并不是一个编程语言,但如果没有DOM, JavaScript 语言也不会有任何网页,XML页面以及涉及到的元素的概念或模型。在文档中的每个元素— 包括整个文档,文档头部, 文档中的表格,表头,表格中的文本都是文档所属于的文档对象模型(DOM)的一部分,因此它们可以使用DOM和一个脚本语言如 JavaScript,来访问和处理。

开始的时候,JavaScript和DOM是交织在一起的,但它们最终演变成了两个独立的实体。JavaScript可以访问和操作存储在DOM中的内容,因此我们可以写成这个近似的等式:

API (web 或 XML 页面) = DOM + JS (脚本语言)

DOM 被设计成与特定编程语言相独立,使文档的结构化表述可以通过单一,一致的API获得,DOM 也可以使用除JavaScript以外的其他的语言来实现。

用于处理XML文档的DOM元素属性

属性名说明
chilNodes返回当前元素所有子元素的数组
firstChild返回当前元素的第一个下级子元素
lastChild返回当前元素的最后一个子元素
nextSibling返回紧跟在当前元素后面的元素
previousSibling返回紧邻当前元素之前的元素
nodeValue返回节点值
parentNode返回元素的父节点

遍历XML 文档的DOM 元素方法

方法名说明
getElementById(id)返回文档中由id指定的元素
getElementByTagName(name)返回当前元素中指定标记名的子元素的数组
hasChildNodes()返回一个布尔值,指示元素是否有子元素
getAttribute(name)返回指定名称的元素的属性值

3.3 使用DOM动态编辑页面

属性/方法描述
document.createElement(tagName)文档对象上的createElement方法可以创建由tagName指定的元素。如果以串div作为方法参数,就会生成一个div元素
document.createTextNode(text)文档对象的createTextNode方法会创建一个包含静态文本的节点
<element>.appendChild(childNode)appendChild方法将指定的节点增加到当前元素的子节点列表(作为一个新的子节点)。例如,可以增加一个option元素,作为select元素的子节点
<element>.getAttribute(name)获得元素中name属性的值
<element>.setAttribute(name, value)设置元素中name属性的值
<element>.insertBefore(newNode, targetNode)这个方法将节点newNode作为当前元素的子节点插到targetNode元素前面
<element>.removeAttribute(name)这个方法从元素中删除属性name
<element>.removeChild(childNode)这个方法从元素中删除子元素childNode
<element>.replaceChild(newNode, oldNode)这个方法将节点oldNode替换为节点newNode
<element>.hasChildnodes()这个方法返回一个布尔值,指示元素是否有子元素

实例:使用DOM和JavaScript创建动态内容

dynamicContent.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>动态编辑网页</title>
    <script type="text/javascript">
        var xmlHttp;
        var requestType = "";
        function createXMLHttpRequest() {
            if (window.XMLHttpRequest) {
                xmlHttp = new XMLHttpRequest();
            }
            else {
                xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
            }
        }
        function startRequest( requestedList) {
            requestType = requestedList;
            createXMLHttpRequest();
            xmlHttp.onreadystatechange = handleStateChange;
            xmlHttp.open("GET", "library.xml", "true");
            xmlHttp.send(null);
        }
        function handleStateChange() {
            if (xmlHttp.readyState == 4) {
                if (xmlHttp.status == 200) {
                    clearResults();
                    parseResults();
                }
            }
        }
        function clearResults(){
            var header = document.getElementById("header");
            if(header.hasChildNodes()){
                header.removeChild(header.childNodes[0]);
            }
            var tableBody = document.getElementById("resultsBody");
            while(tableBody.childNodes.length>0){
                tableBody.removeChild(tableBody.childNodes[0]);
            }
        }
        function parseResults(){
            var results = xmlHttp.responseXML;
            var items = null;
            var item = null;
            var books = null;
            var magazines = null;
            if(requestType == "books"){
                books = results.getElementsByTagName("books");
                items = books[0].getElementsByTagName("book");
                for(var i = 0;i<items.length;i++){
                    item = items[i];
                    name1 = item.getElementsByTagName("name")[0].firstChild.nodeValue;
                    author = item.getElementsByTagName("author")[0].firstChild.nodeValue;
                    year = item.getElementsByTagName("year")[0].firstChild.nodeValue;
                    price = item.getElementsByTagName("price")[0].firstChild.nodeValue;
                    addTableRow(name1,author,year,price);
                }
            }else if(requestType == "magazines"){
                magazines = results.getElementsByTagName("magazines");
                items = magazines[0].getElementsByTagName("magazine");
                for(var i = 0;i<items.length;i++){
                    item = items[i];
                    name1 = item.getElementsByTagName("name")[0].firstChild.nodeValue;
                    year = item.getElementsByTagName("year")[0].firstChild.nodeValue;
                    volume = item.getElementsByTagName("volume")[0].firstChild.nodeValue;
                    total = item.getElementsByTagName("total")[0].firstChild.nodeValue;
                    addTableRow(name1,year,volume,total);
                }
            }
            var header = document.createElement("p");
            var headerText = document.createTextNode("查询结果如下:");
            header.appendChild(headerText);
            document.getElementById("header").appendChild(header);
            document.getElementById("resultsTable").setAttribute("border","1");
        }

        function addTableRow(p1,p2,p3,p4) {
                var row = document.createElement("tr");
                var cell = createCellWithText(p1);
                row.appendChild(cell);
                cell = createCellWithText(p2);
                row.appendChild(cell);
                cell = createCellWithText(p3);
                row.appendChild(cell);
                cell = createCellWithText(p4);
                row.appendChild(cell);
                document.getElementById("resultsBody").appendChild(row);
        }
        function createCellWithText(text) {
             var cell = document.createElement("td");
             var textNode = document.createTextNode(text);
             cell.appendChild(textNode);
             return cell;
        }
    </script>
</head>
<body>
    <p>查看图书或杂志</p>
    <form action="#">
        <input type="button" value="查看图书" onclick="startRequest('books');" />
        <input type="button" value="查看杂志" onclick="startRequest('magazines');" />
    </form>
    <span id="header"></span>
    <table  id="resultsTable" border="0">
        <tbody id="resultsBody"></tbody>
    </table>
</body>
</html>

library.xml

<?xml version="1.0" encoding="utf-8" standalone="no"?>
<library>
    <books>
        <book id="101">
            <name>Java</name>
            <author>张三</author>
            <year>2021.12</year>
            <price>88.50</price>
        </book>
        <book id="102">
            <name>Oracle</name>
            <author>李四</author>
            <year>2021.11</year>
            <price>33.80</price>
        </book>
        <book id="103">
            <name>MySql</name>
            <author>王五</author>
            <year>2021.12</year>
            <price>33.80</price>
        </book>
        <book id="104">
            <name>HTML</name>
            <author>小明</author>
            <year>2021.12</year>
            <price>33.80</price>
        </book>
    </books>
    <magazines>
        <magazine>
            <name>计算机网络</name>
            <year no="1">2021</year>
            <volume>21</volume>
            <total>147</total>
        </magazine>
        <magazine>
            <name>操作系统</name>
            <year no="1">2021</year>
            <volume>22</volume>
            <total>148</total>
        </magazine>
    </magazines>
</library>

四、AJAX的常用应用

4.1 AJAX适用场景

  1. 表单驱动的交互
  2. 深层次的树的导航
  3. 快速的用户与用户间的交流响应
  4. 类似投票、yes/no等无关痛痒的场景
  5. 对数据进行过滤和操纵相关数据的场景
  6. 普通的文本输入提示和自动完成的场景

4.2 AJAX不适用场景

  1. 部分简单的表单
  2. 搜索
  3. 基本的导航
  4. 替换大量的文本
  5. 对呈现的操纵
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JAVA开发区

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值