AJAX
一.XMLHttpRequest的概述
1.XMLHttpRequest最早是在IE5中以ActiveX组件的形式实现的,非W3C标准。
2.创建XMLHttpRequest对象(由于非标准所以实现方法不统一)。
a.Internet Explorer把XMLHttpRequest实现为一个ActiveX对象。
b.其他浏览器(Firefox、safari、Opera...)把它实现为一个本地的JavaScript对象。
c.XMLHttpRequest在不同浏览器上的实现是兼容的,所以可以用同样的方式访问XMLHttpRequest实例的属性和方法,而不论这个实例创建的方法是什么。
二.创建XMLHttpRequest对象
为了每次写Ajax的时候都节省一点时间,可以把对象检测的内容打包成一个可复用的函数:
1 function getHTTPObject(){ 2 var xhr=false; 3 if(window.XMLHttpRequest){ 4 xhr=new XMLHttpRequest(); 5 }else if(window.ActiveXObject){ 6 xhr=new ActiveXObject("Microsoft.XMLHTTP"); 7 } 8 return xhr; 9 }
说明:对window.XMLHttpRequest的调用会返回一个对象或null,if语句会把调用返回的记过看做是true或false(如果返回对象则为true,返回null则为false)。如果XMLHttpRequest对象存在,则把xhr的值设为该对象的新实例。如果不存在,就去检测ActiveObject的实例是否存在,如果答案是肯定的,则把微软XMLHTTP的新实例赋给xhr。
三.XMLHttpRequest的方法
方法 | 描述 |
abort | 停止当前请求 |
getAllResponseHeaders() | 把Http请求的所有响应首部作为键/值对返回 |
getResponseHeader("header") | 返回指定首部的串值 |
open("method","url") | 建立对服务器的调用,Method参数可以使GET、POST或PUT,url参数可以是相对URL或绝对URL |
send(content) | 想服务器发送请求 |
setRequestHeader("header","value") | 把指定首部设置所提供的值。在设置任何首部之前必须先调用open() |
四.XMLHttpRequest的属性
属性 | 描述 |
onreadystatechange | 每个状态改变是都会触发这个事件处理器,通常会调用一个JavaScript函数 |
readyState | 请求的状态,有五个可取值:0=未初始化,1=正在加载,2=已经加载,3=交互中,4=完成 |
responseText | 服务器的响应,表示一个字符串 |
responseXML | 服务器的响应,表示为XML。这个对象可以解析为DOM对象 |
status | 服务器的HTTP状态码(200对应OK,404对应NotFound等) |
statusText | HTTP状态码的相应文本(OK或NotFound等) |
五.发送请求
一.利用XMLHttpRequest实例与服务器进行通信包含以下3个关键部分:
1.onreadystatechange事件处理函数
2.open方法
3.send方法
二.onreadystatechange:
1.该事件处理函数有服务器触发,而不是用户
2.在Ajax执行过程中,服务器会通知客户端当前的通信状态。这依靠更新XMLHttpRequest 对象的readyState来实现。改变readyState属性是服务器对客户端连接操作的一种方式。 每次readyState属性的改变都会触发readystatechange事件。
三.open(method,url,asynch)
1.XMLHttpRequest对象的open方法允许程序员用一个Ajax调用向服务器发送请求的。
2.method:请求类型,类似“GET”或“POST”的字符串。若只想从服务器检索一个文件,而不需要发送任何数据,使用GET(可以在GET请求里通过附加在URL上的查询字符串来发送数据,不过数据大小限制为2000个字符)。若需要向服务器发送数据,用POST。
3.在某些情况下,有些浏览器会把多个XMLHttpRequest请求的结果缓存在同一个URL。如果对每个请求的响应不用,就会带来不好的结果。在此将时间戳加到URL的最后,就能确保URL的唯一性,从而避免浏览器缓存结果。
4.url:路径字符串,只想你锁清秋的服务器上的那个文件。可以是绝对路径或相对路径。
5.asych:表示请求是否要一步传输,默认值为true。指定true,在读取后面的脚本之前,不需要等待服务器的响应。指定false,当脚本处理过程经过这点时,会停下来,一直等到Ajax请求执行完毕再继续执行。
1 <%@ page language="java" contentType="text/html; charset=UTF-8" 2 pageEncoding="UTF-8"%> 3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 4 <html> 5 <head> 6 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 7 <title>Insert title here</title> 8 <script type="text/javascript"> 9 window.onload = function() { 10 //1.获取a节点,并为其添加onclick响应函数 11 document.getElementsByTagName("a")[0].onclick = function() { 12 13 //3.创建一个XMLHttpRequest对象 14 var request = new XMLHttpRequest(); 15 16 //4.准备发送请求的数据:url 17 var url = this.href + "?time=" + new Date(); 18 var method = "GET"; 19 20 //5.调用XMLHttpRequest对象的open方法 21 request.open(method, url); 22 23 //6.调用XMLHttpRequest对象的send方法 24 request.send(null); 25 26 //7.为XMLHttpRequest对象添加 onreadystatechange 响应函数 27 request.onreadystatechange = function() { 28 //8.判断响应是否完成:XMLHttpRequest 对象的 readyState 属性值为4的时候 29 if (request.readyState == 4) { 30 //9.在判断响应是否可用:XMLHttpRequest 对象 status 属性值为200 31 if (request.status == 200 || request.status == 304) { 32 //10.打印响应结果:responseText 33 alert(request.responseText); 34 } 35 } 36 } 37 //2.取消a节点的默认行为 38 return false; 39 } 40 } 41 </script> 42 </head> 43 <body> 44 45 <a href="helloAjax.txt">HelloAjax</a> 46 47 </body> 48 </html>
六.解析HTML
1.HTML由一些普通文本组成。如果拂去其通过XMLHttpRequest发送HTML,文本将存储在responseText属性中
2.不必从responseText属性中读取数据。它已经是希望的格式,可以直接将它插入到页面中。
3.插入HTML代码最简单的方法就是更新这个元素的innerHTML属性。
4.优点:
- 从服务端发送的HTML代码在浏览器端不需要用JavaScript进行解析。
- HTML的可读性好
- HTML代码块与innerHTML属性搭配,效率高
5.缺点:
- 若需要通过AJAX更新一篇文档的多个部分,HTML不合适
- innerHTML并非DOM标准
1 <%@ page language="java" contentType="text/html; charset=UTF-8" 2 pageEncoding="UTF-8"%> 3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 4 <html> 5 <head> 6 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 7 <title>Insert title here</title> 8 <script type="text/javascript"> 9 10 window.οnlοad=function(){ 11 var aNodes=document.getElementsByTagName("a"); 12 for(var i=0;i<aNodes.length;i++){ 13 aNodes[i].οnclick=function(){ 14 15 var request=new XMLHttpRequest(); 16 var method="GET"; 17 var url=this.href; 18 19 request.open(method,url); 20 request.send(null); 21 22 request.onreadystatechange=function(){ 23 if(request.readyState==4){ 24 if(request.status==200 || request.status==304){ 25 document.getElementById("details").innerHTML=request.responseText; 26 } 27 } 28 } 29 30 return false; 31 } 32 } 33 } 34 </script> 35 </head> 36 <body> 37 <h1>People</h1> 38 <ul> 39 <li><a href="files/andy.html">Andy</a></li> 40 <li><a href="files/richard.html">Richard</a></li> 41 <li><a href="files/jeremy.html">Jeremy</a></li> 42 </ul> 43 <div id="details"></div> 44 </body> 45 </html>
七.XML
1.优点:
- XML是一种通用的数据格式。
- 不必把数据强加到已定义好的格式中,而是要为数据自定义合适的标记。
- 利用DOM可以完全掌控文档
2.缺点:
- 如果文档来自于服务器,就必须得保证文档含有正确的首部信息。若文档类型不正确,那么responseXML的值将是空的。
- 当浏览器接收到长的XML文件后,DOM解析可能会很复杂。
1 <%@ page language="java" contentType="text/html; charset=UTF-8" 2 pageEncoding="UTF-8"%> 3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 4 <html> 5 <head> 6 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 7 <title>Insert title here</title> 8 <script type="text/javascript"> 9 10 window.οnlοad=function(){ 11 var aNodes=document.getElementsByTagName("a"); 12 for(var i=0;i<aNodes.length;i++){ 13 aNodes[i].οnclick=function(){ 14 15 var request=new XMLHttpRequest(); 16 var method="GET"; 17 var url=this.href; 18 19 request.open(method,url); 20 request.send(null); 21 22 request.onreadystatechange=function(){ 23 if(request.readyState==4){ 24 if(request.status==200 || request.status==304){ 25 //1.结果为XML格式,所以需要使用responseXML来获取 26 var result=request.responseXML; 27 28 //2.结果不能直接使用,必须先创建对应的节点,再把节点加入到 #details 中 29 //目标格式为: 30 /* 31 <h2><a href="mailto:andy@clearleft.com">Andy Budd</a></h2> 32 <a href="http://andybudd.com">http://andybudd.com</a> 33 */ 34 var name=result.getElementsByTagName("name")[0].firstChild.nodeValue; 35 var website=result.getElementsByTagName("website")[0].firstChild.nodeValue; 36 var email=result.getElementsByTagName("email")[0].firstChild.nodeValue; 37 38 var aNode=document.createElement("a"); 39 aNode.appendChild(document.createTextNode(name)); 40 aNode.href="mailto:"+email; 41 42 var h2Node=document.createElement("h2"); 43 h2Node.appendChild(aNode); 44 45 var aNode2=document.createElement("a"); 46 aNode2.appendChild(document.createTextNode(website)); 47 aNode.href=website; 48 49 var detailsNode=document.getElementById("details"); 50 detailsNode.innerHTML=""; 51 detailsNode.appendChild(h2Node); 52 detailsNode.appendChild(aNode2); 53 } 54 } 55 } 56 57 return false; 58 } 59 } 60 } 61 </script> 62 </head> 63 <body> 64 <h1>People</h1> 65 <ul> 66 <li><a href="files/andy.xml">Andy</a></li> 67 <li><a href="files/richard.xml">Richard</a></li> 68 <li><a href="files/jeremy.xml">Jeremy</a></li> 69 </ul> 70 <div id="details"></div> 71 72 </body> 73 </html>
八.JSON
1.JSON(JavaScript Object Notation)一种简单的数据格式,比XML更轻巧,JSON是JavaScript原生格式,这意味着在JavaScript中处理JSON数据不需要任何特殊的API或工具包。
2.JSON的规则很简单:对象是一个无序的“ ‘名称/值’ ”集合,一个对象以“{”(左括号)开始,“}”(右括号)结束。每个“名称后跟一个“:”(冒号):“ '名称/值' 对”之间使用“,”(逗号)分隔。
3.JSON用冒号(而不是等号)来赋值。每一条赋值语句用逗号分开。整个对象用大括号封装起来。可用大括号分级嵌套数据。
4.对象描述中存储的数据可以是字符串,数字或者布尔值。对象描述也可存储函数,那就是对象的方法。
5.解析JSON
- JSON只是一种文本字符串,它被存储在responseText属性中
- 为了读取存储在responseText属性中的JSON数据,需要根据JavaScript的eval语句。函数eval会把一个字符串当作它的参数。然后这个字符串会被当做JavaScript代码来执行。因为JSON的字符串就是由JavaScript代码构成的,所以它本身是可执行的。
- 代码实例:
1 var jsonResponse=xhr.responseText; 2 var personObject=eval("("+jsonResponse+")"); 3 var name=personObject.person.name; 4 var website=personObject.person.website; 5 var email=personObject.person.email;
- JSON提供了json.js包,下载http://www.json.org/json.js后,使用parseJSON方法将字符串解析成JS对象
1 var jsonResponse=xhr.responseText; 2 var personObject=jsonResponse.parseJSON(); 3 var name=personObject.person.name; 4 var website=personObject.person.website; 5 var email=personObject.person.email;
6.JSON小结
- 优点:
- 作为一种数据传输格式,JSON与XML很相似,但是它更加灵巧。
- JSON不需要从服务器端发送含有特定内容类型的首部信息。
- 缺点:
- 语法过于严谨。
- 代码不易读。
- eval函数存在风险。
1 <%@ page language="java" contentType="text/html; charset=UTF-8" 2 pageEncoding="UTF-8"%> 3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 4 <html> 5 <head> 6 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 7 <title>Insert title here</title> 8 9 <script type="text/javascript"> 10 11 window.οnlοad=function(){ 12 var aNodes=document.getElementsByTagName("a"); 13 for(var i=0;i<aNodes.length;i++){ 14 aNodes[i].οnclick=function(){ 15 16 var request=new XMLHttpRequest(); 17 var method="GET"; 18 var url=this.href; 19 20 request.open(method,url); 21 request.send(null); 22 23 request.onreadystatechange=function(){ 24 if(request.readyState==4){ 25 if(request.status==200 || request.status==304){ 26 //1.结果为XML格式,所以需要使用responseXML来获取 27 var result=request.responseText; 28 var object=eval("(" + result + ")"); 29 30 //2.结果不能直接使用,必须先创建对应的节点,再把节点加入到 #details 中 31 //目标格式为: 32 /* 33 <h2><a href="mailto:andy@clearleft.com">Andy Budd</a></h2> 34 <a href="http://andybudd.com">http://andybudd.com</a> 35 */ 36 var name=object.person.name; 37 var website=object.person.website; 38 var email=object.person.email; 39 40 var aNode=document.createElement("a"); 41 aNode.appendChild(document.createTextNode(name)); 42 aNode.href="mailto:"+email; 43 44 var h2Node=document.createElement("h2"); 45 h2Node.appendChild(aNode); 46 47 var aNode2=document.createElement("a"); 48 aNode2.appendChild(document.createTextNode(website)); 49 aNode.href=website; 50 51 var detailsNode=document.getElementById("details"); 52 detailsNode.innerHTML=""; 53 detailsNode.appendChild(h2Node); 54 detailsNode.appendChild(aNode2); 55 } 56 } 57 } 58 59 return false; 60 } 61 } 62 } 63 </script> 64 </head> 65 <body> 66 <h1>People</h1> 67 <ul> 68 <li><a href="files/andy.js">Andy</a></li> 69 <li><a href="files/richard.js">Richard</a></li> 70 <li><a href="files/jeremy.js">Jeremy</a></li> 71 </ul> 72 <div id="details"></div> 73 </body> 74 </html>
九.对比小结
- 若应用程序不需要与其他应用程序共享数据的时候,使用HTML片段来返回数据时最简单的。
- 如果数据需要重用,JSON文件是个不错的选择,其在性能和文件大小方面有优势。
- 当远程应用程序未知时,XML文档是首选,因为XML是web服务领域的“世界语”。
十.jQuery中的Ajax
1.jQuery对Ajax操作进行了封装,在jQuery中最底层的方法时$.ajax(),第二层是load,$.get(),$.post(),第三层是$.getScript()和$.getJSON()
2.load()方法
- load()方法是jQuery中最为简单和常用的Ajax方法,能载入远程的HTML代码插入到DOM中,它的机构是:load(url,[data],[callback]);
参数名称 | 类型 | 说明 |
url | String | 请求HTML页面的URL地址 |
data(可选) | Object | 发送到服务器的key/value数据 |
callback(可选) | Function | 请求完成时的回调函数,无论请求成功或失败 |
- 程序员只需要使用jQuery选择器为HTML片段指定目标位置,然后将要加载的文件的url做为参数传递给load()方法即可。
3.load()方法---细节
- 如果只需要加载目标HTML页面内的某些元素,则可以通过load()方法的URL参数来达到目的,通过URL参数指定选择符,就可以方便的从加载过来的HTML文档中选出所需要的内容,load()方法的URL参数的语法结构为"url selector"(注意:url和选择器之间有一个空格)。
- 传递方式:load()方法的传递参数根据参数data来自动自定,如果没有参数传递,采用GET方式传递,否则采用POST方式。
- 对于必须在加载完才能继续的操作,load()方法提供了回调函数,该函数有三个参数:代表请求返回内容的data;代表请求状态的textStatus对象和XMLHttpRequest对象。
4.$.get() (或$.post())方法
- $.get()方法使用GET方式来进行异步请求,它的结构是:$.get(url,data,callback,type);
参数名称 | 类型 | 说明 |
url | String | 请求HTML页面的URL地址 |
data(可选) | Object | 发送到服务器的key/value数据会作为Query/String附加到请求URL中 |
callback(可选) | Function | 载入成功时回调函数(只有当Response的返回状态时,success才调用该方法)自动请求结果和状态传递给该方法 |
type(可选) | String | 服务器返回内容的格式,包括xml,html,script,json,text和_default |
- $.get()方法的回调函数只有两个参数,data代表返回的内容,可以是XML文档,JSON文件,HTML片段等;textstatus代表请求状态,其值可能为:success,error,notmodify,timeout4种。
- $.get()和$.post()方法时jQuery中的全局函数,而find()等方法都是对jQuery对象进行操作的方法。
十一.小结
1.什么是Ajax?不用刷新页面,但可以和服务端进行通信的方式,使用Ajax的主要方式是XMLHttpRequest对象
2.使用XMLHttpRequest对象实现Ajax,了解。
3.Ajax传输数据的3种方式:
- XML:笨重,解析困难。但XML是通用的数据交换格式。
- HTML:不需要解析可以直接放到文档中,若仅更新一部分区域,但传输的数据不是很方便,且HTML代码需要拼装完成。
- JSON:小巧,有面向对象的特征,且有很多第三方的jar包可以把JAVA对象或集合转为JSON字符串。
- 使用jQuery完成Ajax操作:
a.load方法:可以用于HTML文档的元素节点,把结果直接加为对应节点的子元素。,通常而言,load方法加载后的数据是一个HTML片段。
var $obj=...
var url=...
var args={key:value,...};
$obj(url,args);
b.$.get,$.post,$.getJSON:更加灵活。除去使用load方法的情况,大部分时候都使用这3个方法。
4.
I.基本的使用
//url:Ajax请求的目标URL
//args:传递的参数:JSON类型
//data:Ajax 响应成功后的数据,可能是XML,HTML,JSON
$.get(url,args,function(data){
});
II.请求JSON数据
$.get(url,args,function(data){
},"JSON");
$.post(url,args,function(data){
},"JSON");
$.getJSON(url,args,function(data){
});
5.使用JackSon
- 加入jar包:
a. jackson-annotations-2.2.2.jar
b. jackson-core-2.2.2.jar
c. jackson-databind-2.2.2.jar
- 具体的使用步骤:
I. 创建org.codehaus.jackson.map.ObjectMapper对象
II. 调用ObjectMapper 的 writeValueAsString 方法把java对象或集合转为 JSON 字符串
ObjectMapper mapper=new ObjectMapper();
String jsonStr=mapper.writeValueAsString(customer);
III. 注意:
a. JackSon 根据getter 来定位Json对象的属性,而不是字段!
b. 可以在类的 getter 方法上添加注解:org.codehaus.jackson.annotate.JsonIgnore 在转为JSON对象是以忽略该属性。