目录
- [Ajax(Asynchronous JavaScript and XML)](#Ajax(Asynchronous JavaScript and XML))
-
- 优点
- 传统Web与Ajax的差异
- Ajax工作流程
- [Ajax 经典应用场景](#Ajax 经典应用场景)
- XMLHttpRequest
- [ajax: GET请求和POST请求的区别](#ajax: GET请求和POST请求的区别)
- 传统Ajax实现
- [.ajax()](#.ajax())
- Ajax的其他方法
- [JSON(JavaScript Object Notation)](#JSON(JavaScript Object Notation))
- 在Ajax中使用JSON数据格式
- FastJSON
-
- 入口类:com.alibaba.fastjson.JSON
- [枚举类型 SerializerFeature 定义了多种序列化属性](#枚举类型 SerializerFeature 定义了多种序列化属性)
- 基于表单数据的Ajax请求
-
- .serializeArray()
- [.param()](#.param())
- 代码示例
Ajax(Asynchronous JavaScript and XML)
- 使用JavaScript 和 XML实现的异步刷新技术
- Ajax不是新的编程语言,而是一种使用现有标准的新方法
- Ajax是一种在无需重新加载整个网页的情况下,能够与服务器交换数据并更新部分网页的技术
- Ajax最大的优点是页面无刷新,用户的体验非常好。并且使用异步方式与服务器通信,具有更加迅速的响应能力
优点
- 我们可以使用Ajax进行无刷新,无刷新是指不刷新整个页面,只刷新局部。
- 无刷新的好处: 只更新部分页面,有效利用带宽,提高用户体验
- 只更新部分页面,有效利用带宽
- 提供连续的用户体验
- 提供类似C/S的交互效果,
- 操作更方便
传统Web与Ajax的差异
差异 | 说明 |
---|---|
发送请求方式不同 | 传统Web 浏览器发送同步请求 Ajax技术 异步引擎对象发送请求 |
服务器响应不同 | 传统Web 响应内容是一个完整页面 Ajax技术 响应内容只是需要的数据 |
客户端处理方式不同 | 传统Web 需等待服务器响应完成并重新加载整个页面后用户才能进行操作 Ajax技术 可以动态更新页面中的部分内容,不影响用户在页面进行其他操作 |
Ajax工作流程
Ajax 经典应用场景
- 搜索引擎根据用户输入关键字,自动提示检索关键字
- 动态加载数据,按需取得数据【树形菜单、联动菜单...】
- 改善用户体验。【输入内容前提示、带进度条文件上传...】
- 电子商务应用。 【购物车、邮件订阅...】
- 访问第三方服务。【访问搜索服务、rss 阅读器】
- 页面局部刷新
XMLHttpRequest
- 整个Ajax技术的核心
- 提供异步发送请求的能力
常用方法
方 法 | 说 明 |
---|---|
open( String method, String url, boolean async, String user, String password ) | 创建一个新的HTTP请求 |
send( String data ) | 发送请求到服务器端 |
abort( ) | 取消当前请求 |
setRequestHeader( String header, String value ) | 设置请求的某个HTTP头信息 |
getResponseHeader( String header ) | 获取响应的指定HTTP头信息 |
getAllResponseHeader( ) | 获取响应的所有HTTP头信息 |
事件
- onreadystatechange:指定回调函数
常用属性
- readyState:XMLHttpRequest的状态信息
就绪状态码 | 说 明 |
---|---|
0 | XMLHttpRequest对象未完成初始化 |
1 | XMLHttpRequest对象开始发送请求 |
2 | XMLHttpRequest对象的请求发送完成 |
3 | XMLHttpRequest对象开始读取响应 |
4 | XMLHttpRequest对象读取响应结束 |
- status:HTTP的状态码
状态码 | 说 明 |
---|---|
200 | 服务器正确返回响应 |
404 | 请求的资源不存在 |
500 | 服务器内部错误 |
403 | 没有访问权限 |
... | ...... |
- statusText:返回当前请求的响应状态
- responseText:以文本形式获得响应的内容
- responseXML:将XML格式的响应内容解析成DOM对象
ajax: GET请求和POST请求的区别
步 骤 | 请求方式 | 实 现 代 码 |
---|---|---|
初始化组件 | GET | xmlHttpRequest.open( "GET", url, true ); |
初始化组件 | POST | xmlHttpRequest.open( "POST", url, true ); xmlHttpRequest.setRequestHeader( "Content-Type","application/x-www-form-urlencoded" ); |
发送请求 | GET | xmlHttpRequest.send( null ); |
发送请求 | POST | xmlHttpRequest.send("key=xxx&type=12&year=20124" ); |
传统Ajax实现
html
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>注册</title>
<script type="text/javascript" src="js/jquery-1.12.4.min.js"></script>
<script type="text/javascript">
function validate() {
var name = $("#name").val();
if (name == null || name == "") {
$("#nameDiv").html("用户名不能为空!");
} else {
//1.创建XMLHttpRequest对象
xmlHttpRequest = createXmlHttpRequest();
//2.设置回调函数
xmlHttpRequest.onreadystatechange = callBack;
//3.初始化XMLHttpRequest组件
var url = "userServlet?name=" + name;//服务器端URL地址,name为用户名文本框获取的值
xmlHttpRequest.open("GET", url, true);
//4.发送请求
xmlHttpRequest.send(null);
/* 使用POST方式发送请求
var url = "userServlet";//服务器端URL地址
xmlHttpRequest.open("POST", url, true);
xmlHttpRequest.setRequestHeader("Content-Type",
"application/x-www-form-urlencoded");
var data = "name=" + name;//需要发送的数据信息,name为用户名文本框获取的值
xmlHttpRequest.send(data);
*/
//Ajax 回调函数
function callBack() {
if (xmlHttpRequest.readyState == 4
&& xmlHttpRequest.status == 200) {
var data = xmlHttpRequest.responseText;
if (data == "true") {
$("#nameDiv").html("用户名已被使用!");
} else {
$("#nameDiv").html("用户名可以使用!");
}
}
}//end of callBack()
}
}//end of validate()
/*
*创建XMLHttpRequest对象
*/
function createXmlHttpRequest() {
if (window.XMLHttpRequest) {//返回值为true时说明是新版本IE或其他浏览器
return new XMLHttpRequest();
} else {//返回值为false时说明是老版本IE浏览器(IE5和IE6)
return new ActiveXObject("Microsoft.XMLHTTP");
}
}
</script>
</head>
<body>
<form action="" id="form1">
<table>
<tr>
<td>用 户 名:</td>
<td><input type="text" name="name" id="name"
onblur="validate();" /> <font color="#c00fff">*</font></td>
<td>
<div id="nameDiv" style="display: inline"></div></td>
</tr>
</table>
</form>
</body>
</html>
传统方式实现Ajax的不足
- 步骤繁琐
- 方法、属性、常用值较多不好记忆
- 处理复杂结构的响应数据(如XML格式)比较烦琐
- 浏览器兼容问题
jQuery将Ajax相关操作都进行了封装
$.ajax()
语法
$.ajax( [settings] );
javascript
$.ajax( {
"url" : "url", // 要提交的URL路径
"type" : "get", // 发送请求的方式
"data" : data, // 要发送到服务器的数据
"dataType" : "text", // 指定传输的数据格式
"success" : function(result) { // 请求成功后要执行的代码
},
"error" : function() { // 请求失败后要执行的代码
}
} );
常用属性参数
参 数 | 类 型 | 说 明 |
---|---|---|
url | String | 发送请求的地址,默认为当前页地址 |
type | String | 请求方式,默认为GET |
data | PlainObject或 String或Array | 发送到服务器的数据 |
dataType | String | 预期服务器返回的数据类型,包括:XML、HTML、Script、JSON、JSONP、text |
timeout | Number | 设置请求超时时间 |
global | Boolean | 表示是否触发全局Ajax事件,默认为true |
常用函数参数
参 数 | 类 型 | 说 明 |
---|---|---|
beforeSend | Function ( jqXHR jqxhr,PlainObject settings ) | 发送请求前调用的函数 |
success | Function( 任意类型 result,String textStatus, jqXHR jqxhr ) | 请求成功后调用的函数 参数result:可选,由服务器返回的数据 |
error | Function ( jqXHR jqxhr, String textStatus, String errorThrown) | 请求失败时调用的函数 |
complete | Function ( jqXHR jqxhr,String textStatus ) | 请求完成后(无论成功还是失败)调用的函数 |
html
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>注册</title>
<script type="text/javascript" src="js/jquery-1.12.4.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$("#name").blur(function() {
var name = this.value;
if (name == null || name == "") {
$("#nameDiv").html("用户名不能为空!");
} else {
$.ajax({
"url" : "userServlet", //要提交的URL路径
"type" : "GET", //发送请求的方式
"data" : "name="+name, //要发送到服务器的数据
"dataType" : "text", //指定返回的数据格式
"success" : callBack, //响应成功后要执行的代码
"error" : function() { //请求失败后要执行的代码
alert("用户名验证时出现错误,请稍后再试或与管理员联系!");
}
});
//响应成功时的回调函数
function callBack(data) {
if (data == "true") {
$("#nameDiv").html("用户名已被使用!");
} else {
$("#nameDiv").html("用户名可以使用!");
}
}//end of callBack()
}
});//end of blur()
});
</script>
</head>
<body>
<form action="" id="form1">
<table>
<tr>
<td>用 户 名:</td>
<td><input type="text" name="name" id="name" /> <font color="#c00fff">*</font></td>
<td>
<div id="nameDiv" style="display: inline"></div></td>
</tr>
</table>
</form>
</body>
</html>
后台servlet:
java
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String name = request.getParameter("name");
boolean used = false;
if("ajax".equals(name)){
used = true;
}else{
used = false;
}
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
out.print(used);
out.flush();
out.close();
}
Ajax的其他方法
$.get()
语法
$.get( url [, data] [, success] [, dataType] );
javascript
$.get( url, data, function( result ) {
// 省略将服务器返回的数据显示到页面的代码
} );
以上代码等价于
javascript
$.ajax( {
"url" : url,
"data" : data,
"type" : "get",
"success" : function( result ) {
// 省略代码
}
} );
$.post()
语法
$.post( url [, data] [, success] [, dataType] );
javascript
$.post( url, data, function( result ) {
// 省略将服务器返回的数据显示到页面的代码
} );
以上代码等价于
javascript
$.ajax( {
"url" : url,
"data" : data,
"type" : "post",
"success" : function( result ) {
// 省略代码
}
} );
$.getJson()
语法
$.getJSON( url [, data] [, success] );
javascript
$.getJSON( url, data, function( result ) {
// 省略将服务器返回的数据显示到页面的代码
} );
以上代码等价于
javascript
$.ajax( {
"url" : url,
"data" : data,
"type" : "get",
"dataType" : "json",
"success" : function( result ) {
// 省略代码
}
} );
.load() [了解]
- 返回HTML内容并设置到元素中
- 不是全局函数
- 匿名的回调函数
- 默认使用GET方式
JSON(JavaScript Object Notation)
- 一种轻量级的数据交换格式
- 采用独立于语言的文本格式
- 通常用于在客户端和服务器之间传递数据
JSON的优点
- 轻量级交互语言
- 结构简单
- 易于解析
定义JSON对象
var JSON对象 = { "name" : value, "name" : value, ...... };
javascript
var person = { "name" : "张三", "age" : 30, "spouse" : null };
定义JSON数组
var JSON数组 = [ value, value, ...... ];
javascript
var countryArray = [ "中国", "美国", "俄罗斯" ];
var personArray = [ { "name":"张三", "age":30 },{ "name":"李四", "age":40 } ];
JSON使用综合案例
html
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>注册</title>
<script type="text/javascript" src="js/jquery-1.12.4.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
//1、定义JSON格式的user对象,并在div中输出
var user = {
"id" : 1,
"name" : "张三",
"pwd" : "000"
};
$("#objectDiv").append("ID:" + user.id + "<br>")
.append("用户名:" + user.name + "<br>")
.append("密码:" + user.pwd + "<br>");
//2、定义JSON格式的字符串数组,并在ul和select中输出
var ary = [ "中", "美", "俄" ];
var $ary = $(ary);
var $ul = $("#arrayUl"); // 展示数据的ul元素
var $sel = $("#arraySel"); // 展示数据的select元素
$ary.each(function() { $ul.append("<li>"+this+"</li>"); });
$ary.each(function(i) {
$sel.append("<option value='"+(i+1)+"'>"+this+"</option>");
});
//3、定义JSON格式的user对象数组,并使用<table>输出
var userArray = [ {
"id" : 2,
"name" : "admin",
"pwd" : "123"
}, {
"id" : 3,
"name" : "詹姆斯",
"pwd" : "11111"
}, {
"id" : 4,
"name" : "梅西",
"pwd" : "6666"
} ];
var $table = $("<table border='1'></table>").append(
"<tr><td>ID</td><td>用户名</td><td>密码</td></tr>");
$(userArray).each(function() {
$table.append("<tr><td>" + this.id + "</td><td>"
+ this.name + "</td><td>"
+ this.pwd + "</td></tr>");
});
$("#objectArrayDiv").append($table);
});
</script>
</head>
<body>
一、JSON格式的user对象:<div id="objectDiv"></div><br>
二、JSON格式的字符串数组: <select id="arraySel"></select>
<ul id="arrayUl"></ul>
三、JSON格式的user对象数组:<div id="objectArrayDiv"></div>
</body>
</html>
在Ajax中使用JSON数据格式
javascript
jQuery(document).ready(function($) {
function initNews() {//使用Ajax技术获取新闻列表数据
$.ajax({
"url" : "../util/news",
"type" : "GET",
"data" : "opr=list",
"dataType" : "json",
"success" : processNewsList
});
}
function processNewsList(data) {//展示新闻列表
var $newsList = $("#opt_area>ul");
for (var i = 0; i < data.length;) {
$newsList.append("<li>" + data[i].ntitle + "<span> 作者:"
+ data[i].nauthor + "      "
+ "<a href='#'>修改</a>      "
+ "<a href='#' οnclick='return clickdel()'>删除</a>"
+ "</span></li>");
if ((++i) % 5 == 0) {
$newsList.append("<li class='space'></li>");
}
}
}
initNews();//执行新闻列表初始化工作
});
后台servlet代码:
java
List<News> list = newsService.findAllNews();
News news = null;
StringBuffer newsJSON = new StringBuffer("[");
for (int i = 0;;) {
news = list.get(i);
newsJSON.append("{\"nid\":" + news.getNid() + ",");
newsJSON.append("\"ntitle\":\""
+ news.getNtitle().replace("\"", """) + "\",");
newsJSON.append("\"nauthor\":\""
+ news.getNauthor().replace("\"", """) + "\"}");
if ((++i) == list.size()) {
break;
} else {
newsJSON.append(",");
}
}
newsJSON.append("]");
out.print(newsJSON);
out.flush();
out.close();
FastJSON
- 随着JSON的广泛使用,在服务器端生成JSON字符串成了一件麻烦的工作,效率低且易出错
- FastJSON:一个性能很好的、Java实现的JSON解析器和生成器
- 将Java对象序列化成JSON字符串
- 将JSON字符串反序列化得到Java对象
- 官网:https://github.com/alibaba/fastjson/releases
入口类:com.alibaba.fastjson.JSON
方 法 | 说 明 |
---|---|
public static String toJSONString ( Object object ) | 将Java对象序列化成JSON字符串 |
public static String toJSONString (Object object, boolean prettyFormat ) | prettyFormat为true时生成带格式的JSON字符串 |
public static String toJSONString ( Object object, SerializerFeature... features ) | 可以通过参数features指定更多序列化规则 |
public static String toJSONStringWithDateFormat (Object object, String dateFormat, SerializerFeature... features ) | 可以通过参数dateFormat指定日期类型的输出格式 |
枚举类型 SerializerFeature 定义了多种序列化属性
枚 举 值 | 说 明 |
---|---|
QuoteFieldNames | 为字段名加双引号,默认即使用 |
WriteMapNullValue | 输出值为null的字段,默认不输出 |
WriteNullListAsEmpty | 将值为null的List字段输出为[ ] |
WriteNullStringAsEmpty | 将值为null的String字段输出为"" |
WriteNullNumberAsZero | 将值为null的数值字段输出为0 |
WriteNullBooleanAsFalse | 将值为null的Boolean字段输出为false |
SkipTransientField | 忽略transient字段,默认即忽略 |
PrettyFormat | 格式化JSON字符串,默认不格式化 |
java
// 包含值为 null 的字段,数值为 null 输出0,String 为 null 输出""
String strJSON = JSON.toJSONString ( javaObject,
SerializerFeature.WriteMapNullValue,
SerializerFeature.WriteNullNumberAsZero,
SerializerFeature.WriteNullStringAsEmpty );
代码示例
java
List<News> list = newsService.findAllNews();
String newsJSON = JSON.toJSONStringWithDateFormat(list,
out.print(newsJSON);
out.flush();
out.close();
基于表单数据的Ajax请求
- 需要发送表单数据时,提取表单元素的值并构造成合适的数据格式是件很烦琐的事。
- 使用jQuery提供的方法简化处理
- .serializeArray()
- $.param()
.serializeArray()
检测一组表单元素中的有效控件
- 没有被禁用
- 必须有name属性
- 选中的checkbox或radio
- 触发提交事件的submit按钮
- file元素不会被序列化
将有效控件序列化为JSON对象数组
- 包含name和value两个属性
$.param()
将由. serializeArray()生成的对象数组序列化成请求字符串的形式
jQuery还提供了.serialize()方法。.serialize()内部使用$.param()对.serializeArray()做了一个简单包装。不需要中间环节时,可以更简便地完成表单数据的序列化
代码示例
javascript
jQuery(document).ready(function($) {
function initNews() {//使用Ajax技术获取新闻列表数据
$.getJSON("../util/news", "opr=list", processNewsList);
}
function processNewsList(data) {//展示新闻列表
var $newsList = $("#opt_area>ul").empty();
for (var i = 0; i < data.length;) {
$newsList.append("<li>" + data[i].ntitle + "<span> 作者:"
+ data[i].nauthor + "      "
+ "<a href='#'>修改</a>      "
+ "<a href='#' οnclick='return clickdel()'>删除</a>"
+ "</span></li>");
if ((++i) % 5 == 0) {
$newsList.append("<li class='space'></li>");
}
}
}
/*
function initNews() {//使用Ajax技术获取新闻列表数据
$("#opt_area>ul").load("../util/news", "opr=listHtml");
}
*/
initNews();//执行新闻列表初始化工作
function initTopics() {//使用Ajax技术获取主题列表数据
$.getJSON("../util/topics", "opr=list", processTopicsList);
}
function processTopicsList(data) {//展示主题列表
var $topicsList = $("#opt_area>ul").empty();
for (var i = 0; i < data.length; ++i) {
$topicsList.append("<li>      "
+ data[i].tname + "      "
+ "<a href='../newspages/topic_modify.jsp?tid="
+ data[i].tid + "&tname=" + data[i].tname + "'>修改</a>"
+ "      <a href='../util/topics?opr=del&tid="
+ data[i].tid + "'>删除</a> </li>");
}
}
/*
function initTopics() {//使用Ajax技术获取主题列表数据
$("#opt_area>ul").load("../util/topics", "opr=listHtml");
}
*/
var $leftLinks = $("#opt_list a"); // 获取页面左侧功能链接
$leftLinks.eq(3).click(initTopics);
$leftLinks.eq(1).click(initNews);
});