1. 概述
- AJAX(Asynchronous JavaScript and XML)是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。
- 通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。
- 传统的网页(不使用 AJAX)如果需要更新内容,必需刷新整个网页。
- Google 通过其 Google Suggest 使 AJAX 变得流行起来。
2. XMLHttpRequest 对象
2.1. 创建
所有现代浏览器(IE7+、Firefox、Chrome、Safari 以及 Opera)均内建 XMLHttpRequest 对象。
xhr=new XMLHttpRequest();
而 IE5 和 IE6使用 ActiveX 对象。
xhr=new ActiveXObject("Microsoft.XMLHTTP");
所以为了兼容所有的现代浏览器
var xhr; if (window.XMLHttpRequest){ // code for IE7+, Firefox, Chrome, Opera, Safari xhr = new XMLHttpRequest(); } else { // code for IE6, IE5 xhr = new ActiveXObject("Microsoft.XMLHTTP"); }
2.2. 方法与属性
XMLHttpRequest对象的方法
方法 作用 abort() 停止当前请求 getAllResponseHeader(header) 把响应的所有头部作为键值对返回 getResponseHeader(header) 返回指定头部的值 open(method,url,async) 建立对服务器的请求。 send(string) 将请求发送到服务器 setRequestHeader(header,value) 把指定头部设置为所提供的值,在设置任何头部前必须先调用open() XMLHttpRequest对象的属性
属性 作用 onreadystatechange 每个状态的改变都会触发这个事件处理器,通常会调用一个JavaScript函数 readyState 请求的状态。 responseText 服务器的响应。表示为字符串。 responseXML 服务器的响应。表示为XML,这个对象可以解析为DOM对象 status 服务器的Http状态码(200对应OK,404对应NotFound等) statusText Http状态码的对应文本(OK或NotFound等)
2.3. 发送请求
如需将请求发送到服务器,我们使用 XMLHttpRequest 对象的 open() 和 send() 方法。
- 网页代码
<html>
<head>
<title>DEMO</title>
<script type="text/javascript">
window.onload = function(){
//获取a节点,并为其添加 onclick 函数
document.getElementsByTagName("a")[0].onclick = function () {
//创建XMLHttpRequest对象
var xhr = new XMLHttpRequest();
var url = this.href;
var method = "GET";
xhr.open(method,url);
xhr.send(null);
//为XMLHTTPRequest对象添加 onreadystatechange 函数
xhr.onreadystatechange = function () {
//判断响应是否完成且响应是否成功
if(xhr.readyState === 4&&xhr.status === 200){
//打印响应结果
alert(xhr.responseText)
}
};
return false;
}
}
</script>
</head>
<body>
<a href="helloAjax.txt">Hello Ajax!</a>
</body>
</html>
helloAjax.txt文件
Hello Ajax!
上面的例子用了 onreadystatechange
,每当 readyState
属性改变时,就会调用onreadystatechange
的函数。
open(method, url, asynch)
method
:请求类型,类似 “GET”或”POST”的字符串。若只想从服务器检索一个文件,而不需要发送任何数据,使用GET(可以在GET请求里通过附加在URL上的查询字符串来发送数据,不过数据大小限制为2000个字符)。若需要向服务器发送数据,用POST。在某些情况下,有些浏览器会把多个XMLHttpRequest请求的结果缓存在同一个URL。如果对每个请求的响应不同,就会带来不好的结果。在此将时间戳追加到URL的最后,就能确保URL的唯一性,从而避免浏览器缓存结果。
javascript
var url = this.href + "?time=" + new Date();
url
:路径字符串,指向你所请求的服务器上的那个文件。可以是绝对路径或相对路径。asynch
:表示请求是否要异步传输,默认值为true
。指定true,在读取后面的脚本之前,不需要等待服务器的相应。指定false,当脚本处理过程经过这点时,会停下来,一直等到Ajax请求执行完毕再继续执行。
readyState
- readyState 属性表示Ajax请求的当前状态。它的值用数字代表。
0 代表未初始化。 还没有调用 open 方法。
1 代表服务器连接已建立。 open 方法已被调用,但 send 方法还没有被调用。
2 代表请求已接收。send 已被调用。请求已经开始。
3 代表请求处理中。服务器正在发送响应。
4 代表请求已完成。响应发送完毕。 - 每次
readyState
值的改变,都会触发readystatechange
事件。如果把onreadystatechange
事件处理函数赋给一个函数,那么每次readyState
值的改变都会引发该函数的执行。 readyState
值的变化会因浏览器的不同而有所差异。但是,当请求结束的时候,每个浏览器都会把readyState
的值统一设为4
。
- readyState 属性表示Ajax请求的当前状态。它的值用数字代表。
responseText
XMLHttpRequest
的responseText
属性包含了从服务器发送的数据。它是一个HTML,XML或普通文本,这取决于服务器发送的内容。
当readyState
属性值变成4
时,responseText
属性才可用,表明Ajax
请求已经结束。
3. 数据格式
- 从服务器端接收数据的时候,那些数据必须以浏览器能够理解的格式来发送。服务器端的编程语言只能以如下 3 种格式返回数据:
- XML
- JSON
- HTML
3.1. 解析XML
- 解析XML优点:
- XML 是一种通用的数据格式。
- 不必把数据强加到已定义好的格式中,而是要为数据自定义合适的标记。
- 利用 DOM 可以完全掌控文档。
- 解析XML缺点:
- 如果文档来自于服务器,就必须得保证文档含有正确的首部信息。若文档类型不正确 ,那么 responseXML 的值将是空的。
- 当浏览器接收到长的 XML 文件后, DOM 解析可能会很复杂。
3.2. 解析HTML
- HTML 由一些普通文本组成。如果服务器通过
XMLHttpRequest
发送 HTML, 文本将存储在responseText
属性中。 - 不必从
responseText
属性中读取数据。它已经是希望的格式,可以直接将它插入到页面中。 插入 HTML 代码最简单的方法是更新这个元素的
innerHTML
属性。解析HTML优点:
- 从服务器端发送的 HTML 代码在浏览器端不需要用 JavaScript 进行解析。
- HTML 的可读性好。
- HTML 代码块与 innerHTML 属性搭配,效率高。
- 解析HTML缺点:
- 若需要通过 AJAX 更新一篇文档的多个部分,HTML 不合适。
- innerHTML 并非 DOM 标准。
3.3. 解析JSON
3.3.1 JSON
- JSON(JavaScript Object Notation)一种简单的数据格式,比 xml 更轻巧。JSON 是 JavaScript 原生格式,这意味着在 JavaScript 中处理 JSON 数据不需要任何特殊的API或工具包。
- JSON的规则很简单:对象是一个无序的 “键值对” 集合。一个对象以”{“(左括号)开始,”}”(右括号)结束。每个”名称”后跟一个”:”(冒号);”键值对”之间使用”,”(逗号)分隔。
例如
var person = { "name":"chen", "age":"3", "address":{"city":"chengdu"} "say":function () { alert("json"); } };
JSON 用冒号(而不是等号)来赋值。每一条赋值语句用逗号分开。整个对象用大括号包裹起来。可用大括号分级嵌套数据。
- 对象描述中存储的数据可以是字符串,数字或者布尔值。对象描述也可存储函数,那就是对象的方法。
3.3.2 解析JSON
JSON 只是一种文本字符串。它被存储在
responseText
属性中。为了读取存储在
responseText
属性中的 JSON 数据,需要根据 JavaScript 的eval
语句。函数eval
会把一个字符串当作它的参数。然后这个字符串会被当作 JavaScript 代码来执行。因为 JSON 的字符串就是由 JavaScript 代码构成的,所以它本身是可执行的。也可以用
JSON.parse()
来解析Json。其语法为JSON.parse(text[, reviver])
,text
是一个有效的 JSON 字符串,而reviver
是一个转换结果的函数,将为对象的每个成员调用此函数。var xhr = new XMLHttpRequest(); var object1 = eval("("+ xhr.responseText +")"); var object2 = JSON.parse(xhr.responseText);
解析JSON优点:
- 作为一种数据传输格式,JSON 与 XML 很相似,但是它更加灵巧。
- JSON 不需要从服务器端发送含有特定内容类型的首部信息。
解析JSON缺点:
- 语法过于严谨
- 代码不易读
4. jQuery中的Ajax
jQuery 对 Ajax 操作进行了封装, 在 jQuery 中最底层的方法时 $.ajax()
, 第二层是 load()
, $.get()
和 $.post()
, 第三层是 $.getScript()
和 $.getJSON()
。
4.1. load()方法
load() 方法是 jQuery 中最为简单和常用的 Ajax 方法, 从服务器载入数据并且将返回的 HTML 代码并插入至匹配的元素 中。它的语法结构是:
load(url[, data][,callback])
。属性 类型 描述 url String 一个包含发送请求的URL字符串 data(可选) Object 向服务器发送请求的Key/value参数,例如{name:”goudan”,age:23} callback(可选) Function 当请求成功后执行的回调函数。 如果只需要加载目标 HTML 页面内的某些元素, 则可以通过 load() 方法的 URL 参数来达到目的. 通过 URL 参数指定选择符, 就可以方便的从加载过来的 HTML 文档中选出所需要的内容. load() 方法的 URL 参数的语法结构为 “url selector“(注意: url 和 选择器之间有一个空格)。
//只选择h2
var url = this.href+" h2";
- 传递方式: load() 方法的传递参数根据参数 data 来自动指定. 如果没有参数传递, 采用 GET 方式传递, 否则采用 POST 方式。
对于必须在加载完才能继续的操作, load() 方法提供了回调函数, 该函数有三个参数: 代表请求返回内容的 data; 代表请求状态的 textStatus 对象和 XMLHttpRequest 对象。
解析HTML
//使用load方法 $(function(){ $("a").click(function(){ var url = this.href+" h2"; var args = {"time":new Date()}; $("#result").load(url,args); return false; }); })
4.2. $.get()
或$.post()
方法
$.get()
方法使用GET
方式来进行异步请求. 它的结构是:$.get(url[, data][, callback][, type])
。属性 类型 描述 url String 一个包含发送请求的URL字符串 data(可选) Object 发送给服务器的字符串或Key/value键值对。 callback(可选) Function 当请求成功后执行的回调函数。 dataType(可选) String 从服务器返回的预期的数据类型。默认:智能猜测(xml, json, script, 或 html)。 $.get()
方法的回调函数只有两个参数:data
代表返回的内容, 可以是 XML 文档, JSON 文件, HTML 片段等;textstatus
代表请求状态, 其值可能为:succuss
,error
,notmodify
,timeout
4 种。解析XML
//使用$.get方法
$(function(){
$("a").click(function(){
var url = this.href;
var args = {"time":new Date()};
$.get(url,args,function(data){
var name = $(data).find("name").text;
var email = $(data).find("email").text;
$("#result").empty()
.append("<h2><a href='" + email +"'>"+name+ "</a></h2>");
});
return false;
});
})
- 解析JSON
//使用$.get方法
$(function(){
$("a").click(function(){
var url = this.href;
var args = {"time":new Date()};
//第一种方法,加入type参数
$.get(url,args,function(data){
var name = data.person.name;
var email = data.person.email;
$("#result").empty()
.append("<h2><a href='" + email +"'>"+name+ "</a></h2>");
},"JSON");
//第二种方法,直接使用getJSON
/*$.getJSON(url,args,function(data){
var name = data.person.name;
var email = data.person.email;
$("#result").empty()
.append("<h2><a href='" + email +"'>"+name+ "</a></h2>");
});*/
return false;
});
})
5. 使用Jackson
- Jackson 需要三个 jar 包:
- jackson-core-2.9.2.jar(核心jar包)
- jackson-annotations-2.9.2.jar(该包提供Json注解支持)
- jackson-databind-2.9.2.jar
- 而一个mvn依赖就可以了
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.2</version>
</dependency>
例子
person类
public class Person { private String id; private String name; public Person(String id, String name) { this.id = id; this.name = name; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getCity() { return "Chengdu"; } public String getBirth() { return "1000-01-02"; } }
可以看到该类只有两个字段,有四个
getter
方法,jackson
是依据getter
方法来确定 json 对象的属性。- ObjectMapper 是JSON操作的核心,而 writeValueAsString(Object value)可以把java的 value对象序列化为json字符串。
测试方法
@Test public void testJackson() throws JsonProcessingException { ObjectMapper objectMapper = new ObjectMapper(); Person person = new Person("1","狗蛋"); //{"id":"1","name":"狗蛋","birth":"1000-01-02","city":"Chengdu"} System.out.println(objectMapper.writeValueAsString(person)); }
而此时用
com.fasterxml.jackson.annotation.JsonIgnore
注解加在getter
方法上面,可以来让jackson
忽略某个getter
属性@JsonIgnore public String getBirth() { return "1000-01-02"; }
此时控制台打印
{"id":"1","name":"狗蛋","city":"Chengdu"}