第三章 使用XMLHttpRequest对象 Ajax软件开发技术 第三章 使用XMLHttpRequest对象
本章内容 XMLHttpRequest对象概述 XMLHttpRequest的属性和方法 XMLHttpRequest交互实例 GET 与POST 远程脚本 发送简单请求 DOM
本章要求 了解XMLHttpRequest对象的作用 理解XMLHttpRequest对象的属性和方法 使用Post和Get方法
本章内容 XMLHttpRequest对象概述√ XMLHttpRequest的属性和方法 XMLHttpRequest交互实例 GET 与POST 远程脚本 发送简单请求 DOM
传统Web应用与Ajax应用的比较
传统Web应用解决方案 在传统的Web应用模型下,大部分的用户操作都会发送一个HTTP请求给服务器,然后服务器开始处理(接收数据,执行业务逻辑,访问数据库等),最后向浏览器返回HTML页面。当服务器处理请求时,用户能够做什么呢?只有等待!
Ajax解决方案 Ajax应用通过在用户和服务器之间引入一个媒介(Ajax engine)来异步发送请求,消除了传统的发送请求-等待-发送请求-等待的特性,极大的提高了用户体验。
XMLHttpRequest对象概述 Asynchronous XMLHttpRequest 最早是在IE5.0中以ActiveX组件的形式出现的 当前Mozilla,Safari,Opera等浏览器厂商都支持XMLHttpRequest对象。 通过XMLHttpRequest对象,Ajax可以像桌面应用程序一样只同服务器进行数据层面的信息交换,而不用每次刷新页面,也不用每次将数据处理的工作都交给服务器来做。这样既减轻了服务器的负担,又加快了响应速度、缩短了用户等待的时间。
XMLHttpRequest 对象的创建 由于XMLHttpRequest并不是W3C的标准,因此不同的浏览器对XMLHttpRequest对象的支持方式不同 在IE中实现为ActiveX对象 其它浏览器如FireFox,实现为本地JavaScript对象 由于存在差别,JavaScript中须包含有关的逻辑,以创建跨浏览器的XMLHttpRequest对象
XMLHttpRequest 对象的创建 var xmlHttp; //声明全局变量 //创建XMLHttpRequest对象 function createXMLHttpRequest(){ if(window.XMLHttpRequest){ //如果是Mozilla浏览器 xmlHttp = new XMLHttpRequest(); } else if(window.ActiveXObject){ //如果是IE浏览器 try{ xmlHttp = new ActiveXObject("Msxml2.XMLHTTP"); }catch(e){ xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); }catch(e){ }
使用XMLHttpRequest对象-同步用法 创建对象 创建请求 发送请求 这与传统Web应用没有区别,仍然是发送请求到服务器,然后等待响应。
使用XMLHttpRequest对象-异步用法 如果是异步使用本对象时,必须使用onreadystatechange事件调用该对象。在触发该事件后,必须在应用程序采取行动之前检查readystate属性的内容。因此,可采用以下模式: 创建该对象。 设置readystatechange事件触发一个指定的函数。
使用XMLHttpRequest对象-异步用法 检查readystate属性,看数据是否准备就绪。如果还未就绪,隔一段时间再次检查。如果已经准备就绪,继续执行下一步。 打开请求。 发送请求。 readystatechange事件的整个操作都是在后台执行,这样就能够异步使用XMLHttpRequest对象。
本章内容 XMLHttpRequest对象概述 XMLHttpRequest的属性和方法√ XMLHttpRequest交互示例 GET 与POST 远程脚本 发送简单请求 DOM
XMLHttpRequest的属性 XMLHttpRequest对象提供了各种属性、方法和事件,以便于脚本处理和控制HTTP请求与响应。 说明 onreadystatechange 每个状态改变时都会触发这个事件处理器,通常会调用一个JavaScript函数 readyState 请求的状态 responseText 服务器的响应,表示为一个串 responseXML 服务器的响应,表示为XML,这个对象可以解析为一个DOM对象 status 服务器的HTTP状态码(200对应OK等) statusText HTTP状态码的相应文本
XMLHttpRequest的属性 XMLHttpRequest对象的readyState属性值表: 属性值 说明 描述一种“未初始化”状态,此时已经创建了一个XMLHttpRequest对象,但是还没有初始化 1 描述一种“发送”状态,此时代码已经调用了XMLHttpRequest.open()方法,并且XMLHttpRequest已经准备好把一个请求发送到服务器对象 2 描述一种“发送”状态,此时已经通过send()方法把一个请求发送到服务器端,但是还没有收到响应 3 描述一种“正在接收”状态,此时已经接收到HTTP响应头部信息,但是消息体部分还没有完全接收结束 4 描述一种“已加载”状态,此时响应已经被完全接收
说明 status和statusText属性: 它的值是http的状态码,通常只在status=200时才进行响应数据处理,但也可根据具体情况在status为其他值时做一些处理。 statusText属性一般用于status不为200时显示详细的http错误状态信息
说明 responseText与responseXML属性: 无论服务器端返回的是XML还是普通的文本内容,html内容,都可以使用responseText属性来获得服务器端的返回值。 当服务器端返回的不是XML内容时,不同的浏览器在获取responseXML属性值时略有不同,IE仍然会获取到一个DOM对象,只不过内容是空的,而FireFox获取到的则是一个null。
说明 如果服务器端要返回普通文本内容,html内容,一般在服务器端会设置响应头信息中的"Content-Type"为text/html,同时为了保证中文信息不会出现乱码,还会根据需要设置"Content-Type"中charset。 如果服务器端要返回xml,首先返回的数据一定要是一个DOM兼容的xml字串,其次需要在服务器端设置响应头信息中的“Content-Type”为text/xml。这样在浏览器端的Javascript代码中可以通过responseXML属性获得一个DOM兼容的XML对象,通过DOM的方式操作XML。
说明 还有一点需要说明的是虽然AJAX倡导使用XML传输数据,但并不是说AJAX模式的程序一定要用XML作为传输数据。
XMLHttpRequest的方法 abort() 停止当前请求 getAllResponseHeaders() 描述 abort() 停止当前请求 getAllResponseHeaders() 返回包含HTTP请求的所有响应头信息,其中响应头包括Content-Length,Date,URI等内容。 返回值是一个字符串,包含所有头信息,其中每一个键名和键值用冒号分开,每一组键之间用CR和LF(回车加换行符)来分隔 getResponseHeader(String header) 返回HTTP请求的响应头中指定的键名header对应的值
XMLHttpRequest的方法 方法 描述 open (String method,String url,boolean asynch,String username,String password) 建立对服务器的调用。 其中method表示HTTP调用方法。一般使用“GET”,“POST” url表示调用的服务器的地址 asynch表示是否采用异步方式,true表示异步 后两个参数可以不指定,username和password分别表示用户名和密码,提供http认证机制需要的用户名和密码 send(content) 向服务器发出请求,如果采用异步方式,该方法会立即返回。 Content可以不指定,其内容可以是DOM对象,输入流或是字符串。 setRequestHeader(String header,String value) 设置HTTP请求中的指定首部header的值为value。 此方法需在open方法以后调用。
本章内容 XMLHttpRequest对象概述 XMLHttpRequest的属性和方法 XMLHttpRequest交互示例√ GET 与POST 远程脚本 发送简单请求 DOM
客户端事件触发Ajax事件 用户名:<input type="text" id="name"/> 这是因为在AJAX模式中,通常在javascript代码中通过DOM获得html页面中某个节点的值,因此一般都定义id属性,这部分的详细内容会在后面介绍。
客户端事件触发Ajax事件 <input type="button" value="Start Basic Asynchronous Request" onclick="startRequest();"/> 与传统Web开发模式不同,页面中没有form,submit换成了一个button,在button的定义中,使用了一个onclick属性。 onclick属性的作用是在点击按钮时,调用该属性所指定的javascript函数。我们可以在onclick属性指定的javascript函数中使用XMLHttpReuqest对象来与服务器端程序(例如一个Servlet)进行数据传输。
客户端事件触发Ajax事件 <div id="result"></div> 另外建立了一个div标签,div标签应该说是AJAX模式下很重要的一个html标签。 前面提到过的基于标准的表示技术,比较常用的一种方式就是用DIV+CSS替代talbe的方式来划分网页结构,div中放内容,css控制这些内容的展现形式。 除此之外,div的另一个常用之处就是用于放置动态加入网页中的内容,先建立一个没有内容的div,再在Javascript代码中通过DOM动态的向其中添加内容,以保证在页面不刷新的情况下动态修改页面内容。这部分的详细内容也会在后面介绍。
发送请求 步骤1:创建XMLHttpRequest对象的一个实例 createXMLHttpRequest();
XMLHttpRequest 对象的创建 var xmlHttp; //声明全局变量 //创建XMLHttpRequest对象 function createXMLHttpRequest(){ if(window.XMLHttpRequest){ //如果是Mozilla浏览器 xmlHttp = new XMLHttpRequest(); } else if(window.ActiveXObject){ //如果是IE浏览器 xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); if(xmlhttp == null){ resultNode.innerHTML = "不能建立XMLHttpRequest对象"; return false;
“window.XMLHttpRequest”为true时表示当前浏览器是IE7或其他浏览器,我们就可以使用new XMLHttpRequest()的方式来创建一个XMLHttpRequest对象 “window.ActiveXObject”为true时表示当前的浏览器为IE6.0及以下的版本,要使用new ActiveXObject(控件名)的方式来创建一个XMLHttpRequest对象 如果没有建立成功XMLHttpRequest对象,则不能继续后面与服务器端交互的工作,函数只能返回。
resultNode.innerHTML这样的用法是为了设置某个节点中的html的内容,这里resultNode代表的是div那个节点,这句话的效果是使div的内容变成了<div id="result">不能建立XMLHttpRequest对象</div>,这样就会在页面中看到这行提示信息。
发送请求 步骤2:告诉XMLHttpRequest对象,当其状态改变时执行哪个函数 xmlHttp.onreadystatechange = callback;
设置一个回调函数 由于AJAX采用异步交互的模型,不像同步模式一样可以直接接收响应内容,因此需要告诉AJAX引擎当响应数据回来时要做一些什么工作,这些工作就是回调函数中的内容。 这里需要注意的是设置回调函数时应该只给出回调函数的名称,后面不要带括号,因为带上括号就变成让XMLHttpRequest对象的onreadystatechange属性值等于回调函数的返回值了。
document.getElementById("result") document.getElementById("name").value document.getElementById的作用是根据id名获得对应的节点(某一个html标签的内容),这里分别用这个语句来获得div和文本框的节点;.value的作用是获得文本框的value属性值,也就是文本框中的内容。
发送请求 步骤3:使用open()方法建立对服务器的调用,并设置URL以及所希望的HTTP方法 //Get方式 var url = "Login?userName=zhangsan"; xmlHttp.open("GET", url, true); //Post方式 (需要设置Content-Type首部) var url = "Login"; xmlHttp.open("POST", url, true); xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
这里第一个参数表示http连接的方法, 一般使用“GET”或“POST”方式,两种方式的区别会在后面阐述。 第二个参数是服务器端地址,由于使用GET方式,因此要传送给服务器端的数据也在URL中,这里如果使用encodeURI,其目的是为了解决URL中的中文信息在服务器端解码的问题,配合服务器端的URLDecoder.decode(old,“UTF-8”)语句可以保证中文信息在服务器端也可以正常被解出。 第三个参数表示是否采用异步方式进行传输,其中true表示采用异步方式,在AJAX中看重的就是异步方式,因此这个参数通常使用true。
发送请求 步骤4:将请求发送给服务器 //Get方式 xmlHttp.send(null); //Post方式 var content = "userName=zhangsan"; xmlHttp.send(content);
发送请求 发送请求的JavaScript函数(Get方式) function sendRequest() { createXMLHttpRequest(); xmlHttp. onreadystatechange = callback; var url = "Login?userName=zhangsan"; xmlHttp.open("GET", url, true); xmlHttp.send(null); }
再接着就是向服务器端发送数据,这里由于已经在URL中包含了发送给服务器的数据,因此在send时就不需要参数了,后面会讲到对于POST模式,这里的使用方式会有不同。
设置回调函数 一旦发出了请求,对象的readyState属性会经过几个变化,每次变化都会调用callback函数。 function callback (){ if(xmlHttp.readyState == 4){ //如果服务器响应结束,信息已返回 if(xmlHttp.status == 200){ //还要确认返回的页面没有错误 //可以开始处理 } else{ //页面有问题 //信息还没有返回,等待
这里readyState=4时表示服务器端的响应数据已经被全部接收,readyState还有其他状态,后面会进行详细介绍。 Status=200表示http连接状态正常,如果不是200,则表示http连接有误,此时回来的数据也不是我们需要的。 当响应数据全部接收并且http连接状态正确时,我们就可以接收响应的数据了,这里可以使用xmlhttp.responseText以文本形式接收响应的数据,也可以用XML方式接收。
本章内容 XMLHttpRequest对象概述 XMLHttpRequest的属性和方法 XMLHttpRequest交互示例 GET 与POST √ 远程脚本 发送简单请求 DOM
GET和POST的区别 “GET”方式传递给服务器的信息一般以后缀参数方式存在于URL地址中,而URL的长度通常都有限制,这也就限制了“GET”方式传递给服务器的内容大小。例如,IE中为2083个字符;Opera中为4050个;Netscape4中为8192个; Netscape6中为2000等。 “POST”方式传递给服务器的信息并不位于URL地址中,所以没有大小限制,可以大量传输数据(最多2GB)。
GET和POST的区别 “GET”方法中数据只能使用ASCII码发送。同时GET请求是可缓存的,而POST请求则永远不缓存。 在服务器端的Servlet中,doGet和doPost做的是一样的工作,但GET请求常用于不会导致变化的查询,如果提交的表单或数据会导致服务器上的状态发生变化,则使用POST方法为首选。
本章内容 XMLHttpRequest对象概述 XMLHttpRequest的属性和方法 XMLHttpRequest交互示例 GET 与POST 远程脚本√ 发送简单请求 DOM
远程脚本概述 远程脚本是一种远程过程调用类型。采用远程脚本可以像正常的Web应用一样与服务器交互,而不用刷新整个页面。 与Ajax类似,可以调用任何服务器端技术来接收请求、处理请求并返回一个有意义的结果。
远程脚本示例 iframe.html Server.html
本章内容 XMLHttpRequest对象概述 XMLHttpRequest的属性和方法 XMLHttpRequest交互示例 GET 与POST 远程脚本 发送简单请求√ DOM
发送简单请求示例
小结 需要注意的内容: 1、不同浏览器下XMLHttpRequest对象的不同的建立方式 ; 2、设置回调函数时不要加括号; 3、 open方法三个参数的含义,GET方式和POST方式服务器端地址的不同写法 ; 4、GET方式和POST方式send的参数的不同之处,以及POST方式下send之前需要设置请求头信息的工作; 5、如何判断正确的响应数据已经返回,以及如何获取响应数据内容。
小结 AJAX应用的五个步骤: 1 建立XMLHttpRequest对象 2 设置回调函数 3 使用open方法与服务器建立连接 2 设置回调函数 3 使用open方法与服务器建立连接 4 向服务器端发送数据 5 在回调函数中针对不同响应状态进行处理
AJAX技术核心--安全 XMLHttpRequest的一个特殊安全问题: IE:访问跨域页面时会给出提示,用户确认后会访问 Mozilla FireFox及其他:不允许访问跨域页面
AJAX技术核心--安全
AJAX技术核心--安全 如何解决跨域问题?
AJAX技术核心--安全 在浏览器端的代码中,需要在调用open方法之前判断一下要连接的地址是不是以http开头的,如果是则认为要访问的是跨域的资源,首先将当前url中的”?”变成”&”,这是因为将要连接的地址改为”Proxy?url=” + url以后,如果原来url地址中有参数的话,新的url地址中就会有两个“?”这会导致服务器端解析参数错误,”url=”之后的内容表示本来要访问的跨域资源的地址。 function convertURL(url){ if(url.substring(0,7) == "http://"){ url = url.replace("?","&"); url = "Proxy?url=" + url; } return url;
AJAX技术核心--安全 注意: Proxy中针对GET方式和POST方式进行了分别的处理,其中GET方式仍然将参数信息拼到URL中,而POST方式则向HttpURLConnection的数据流中添加参数信息。 由于对本来请求的地址和其包含的参数进行了转换,导致url参数中只包含原来请求的地址信息,而原来请求的参数信息则需要我们解析出来和地址信息一起重新组成本来的请求URL。
AJAX技术核心--安全 注意由于进入servelt之前参数信息已经被做过一次URLDecoder,因此这个时候参数信息中的中文信息传到真正要访问的servlet时解码会出现乱码,因此我们在拼接参数信息之前又再一次通过URLEncoder.encode方法对所有参数信息进行了一次编码,这样就解决了中文的乱码问题。 在从远端服务器读取数据时,要显示指定输入流的编码格式,这样才可以保证通过BufferReader读到的内容不会有乱码信息。
本章内容 XMLHttpRequest对象概述 XMLHttpRequest的属性和方法 XMLHttpRequest交互示例 GET 与POST 远程脚本 发送简单请求 DOM √
使用DOM DOM(Document Object Model):被称作文档对象模型,是一个W3C标准,它可以以一种独立于平台和语言的方式访问和修改一个文档的内容、结构和风格。 DOM是以面向对象方式描述的对象模型 。
使用DOM 在AJAX中,DOM对于我们来说是HTML 和 XML 文档的一个应用程序接口,它可以把HTML,XML与AJAX中的开发语言Javascript连接起来。 Javascript中的DOM实现可以使得我们在AJAX中通过Javascript代码对HTML和XML数据进行DOM方式的操作,从而做到页面的动态修改更新和数据的提取处理。
使用DOM 可以把DOM认为是页面上数据和结构的一个树形表示 代码片段 <table> <tbody> <tr> <td>Foo</td> <td>Bar</td> </tr> </tbody> </table>
使用DOM HTML的DOM和XML的DOM在API接口上基本一致,使用差别不大,但本质上有区别。 HTML的DOM是一个内存对象树,在浏览器中只保存一份,HTML的DOM修改HTML的内容会直接反应到浏览器中;而XML的DOM则可以创建多个,每个可以对应一个XML文本。
DOM中的相关属性和方法 在DOM眼中,HTML或XML是由很多不同类型的节点组成的,这些节点都属于NODE对象。 NODE对象有一个nodeType的属性可用于判断节点类型 接口 nodeType常量 nodeType值 备注 Element Node.ELEMENT_NODE 1 元素节点 Attr Node.ATTRIBUTE_NODE 2 节点属性 Text Node.TEXT_NODE 3 文本节点 Comment Node.COMMENT_NODE 8 注释节点 Document Node.DOCUMENT_NODE 9 Document根节点
DOM中的相关属性和方法 元素节点是HTML中最常见的节点,页面中的<body>,<input>,<div>都是元素节点。 属性节点表示的是一个元素节点的某个属性,例如<input>中的value属性就可以被看作一个属性节点。 文本节点表示HTML页面中的一段文字信息,例如<div>Hello World</div>,其中的”Hello World”就是一个文本节点。
DOM中的相关属性和方法 注释文本节点也比较好理解,HTML的注释信息,<!—Comment Message-->比如这样一段内容就是一个注释文本节点。 根节点顾名思义,表示的是HTML的根,在Javascript中有一个特殊的对象document,它可以表示HTML的根节点,后面我们会介绍这个特殊对象有很多在AJAX中非常常用的方法。
DOM中的相关属性和方法 根节点的属性和方法 属性 描述 documentElement 表示文档的根元素节点 在HTML文档中,它表示<html>这个标签代表的元素节点 方法 createAttribute() 用指定名字创建新的Attr节点对象。 方法参数为属性的名字 createComment() 用指定的字符串创建新的Comment节点对象。 方法参数为注释信息 createElement() 用指定的标记名创建新的Element节点对象。 方法参数为节点标签的名字
DOM中的相关属性和方法 根节点的属性和方法 方法 描述 createTextNode() 用指定的文本创建新的文本节点对象。 方法参数为文本信息 getElementById() 返回文档中具有指定id属性的Element节点。 方法参数为节点的id属性值 getElementsByTagName() 以数组方式返回文档中具有指定标记名的所有Element节点,其顺序为在文档中出现的顺序。标记名指的是像body,table这样的HTML标记名称。 方法参数为标记名称
DOM中的相关属性和方法 Element节点对象的常用方法都是对节点属性的操作。 属性 描述 tagName 元素的标记名字,例如<table>元素的标记名字为table。 HTML文档返回的标记名字均为大写。 方法 getAttribute() 以字符串形式返回指定属性的值 方法参数为属性名称 getAttributeNode() 以Attr节点对象的形式返回指定属性的值 getElementsByTabName() 以数组方式返回当前元素节点的子孙节点中中具有指定标记名的所有Element节点,其顺序为在文档中出现的顺序。 方法参数为节点的标记名
DOM中的相关属性和方法 Element节点对象的常用方法都是对节点属性的操作。 方法 描述 hasAttribute() 如果该元素具有指定名字的属性,则返回true removeAttribute() 从Element节点中删除指定的属性 方法参数为属性的名称 removeAttributeNode() 从Element节点的属性列表中删除指定的Attr节点 setAttribute() 把指定的属性设置为指定的字符串值,如果该属性不存在则添加一个新属性 方法的第一个参数为属性的名称 方法的第二个参数为属性的值 setAttributeNode() 把指定的Attr节点添加到该元素的属性列表中 方法的参数为Attr节点对象
DOM中的相关属性和方法 属性节点的属性 属性 描述 name 属性名 value 属性值
DOM中的相关属性和方法 Node对象的属性和方法如下所示 : 属性 描述 attributes 表示该节点的所有属性节点对象的数组 childNodes 表示当前节点的子节点的数组。如果没有子节点,则返回空数组 firstChild 返回当前节点的第一个子节点。如果没有子节点,则返回null lastChild 返回当前节点的最后一个子节点。如果没有子节点,则返回null nextSibling 返回当前节点的下一个兄弟节点。如果没有这样的节点,则返回null
DOM中的相关属性和方法 Node对象的属性和方法如下所示 : 属性 描述 previousSibling 返回当前节点的上一个兄弟节点。如果没有这样的节点则返回null nodeName 返回节点的名字,对于Element节点表示Element的标记名称 nodeType 代表节点的类型 nodeValue 代表节点的内容。对于Text节点,nodeValue的值是文本内容。对于注释节点,nodeValue的值是注释内容。对于属性节点,nodeValue的值是属性值。对于其他节点,nodeValue的值可能为null。 parentNode 返回当前节点的父节点。如果没有父节点,则返回null
DOM中的相关属性和方法 Node对象的属性和方法如下所示 : 方法 描述 appendChild() 给当前节点增加一个子节点。增加的子节点位于当前节点的所有子节点的末尾。 方法参数为Node对象。 cloneNode() 复制当前节点,或者复制当前节点以及它的所有子孙节点。 方法参数为true或false。True表示递归的复制所有子孙节点,false表示只复制当前节点。 hasChildNodes() 如果当前节点拥有子节点,则返回true
DOM中的相关属性和方法 Node对象的属性和方法如下所示 : 方法 描述 insertBefore() 插入一个节点,位置在当前节点的指定子节点之前。如果该节点已经存在,则删除原节点后再插入新的节点。如果指定子节点不存在,则执行效果和appendChild方法相同。 方法第一个参数是要插入的节点。 方法第二个参数是当前节点的指定子节点,新插入的节点位于这个节点之前。 removeChild() 从文档树中删除并返回指定的子节点。 方法的参数是要删除的子节点 replaceChild() 从文档树中删除并返回指定的子节点,用另一个节点替换它。 方法第一个参数是新的子节点。 方法第二个参数是被替换的子节点。
使用DOM DOM提供一套表示文档结构的对象,以及访问这些对象的方法。 利用DOM中的对象,开发人员可以对XML和HTML文档进行读取、搜索、修改、添加和删除等操作。
使用DOM操作HTML文档
使用DOM操作XML文档 相对HTML文档而言,XML文档的树型结构更加直观 使用XML文档时,需要解决的问题是,如何方便地对XML树型结构中的结点进行遍历
使用DOM操作XML文档