JS原生Ajax和jQuery的Ajax与代码示例
2018-08-26 20:38:57 苏凯勇往直前 阅读数 17250更多
JS原生Ajax和jQuery的Ajax
【学习目标】
1,了解JS原生Ajax原理
2,掌握json数据格式
- 掌握json数据格式方式
- 掌握json的解析方式
3,掌握jQuery中的Ajax封装
4,使用Ajax实现特效
- 实现异步验证用户名是否存在
- 实现站内搜索功能
- Ajax基本概念
1.1.1 Ajax概述
什么是同步,什么是异步
同步现象:客户端发送请求到服务器端,当服务器返回响应之前,客户端都处于等待 卡死状态
异步现象:客户端发送请求到服务器端,无论服务器是否返回响应,客户端都可以随 意做其他事情,不会被卡死
1.1.2 Ajax的运行原理
页面发起请求,会将请求发送给浏览器内核中的Ajax引擎,Ajax引擎会提交请求到服务器端,在这段时间里,客户端可以进行任意操作,直到服务器端将数据返回给Ajax引擎后,会触发你设置的事件,从而执行自定义的js逻辑代码完成某种功能。Ajax异步请求与同步请求对比如下图所示。
1.2 JS原生的Ajax技术(了解)
js原生的Ajax其实就是围绕浏览器内内置的Ajax引擎对象进行学习的,要使用js原生的Ajax完成异步操作,有如下几个步骤:
1)创建Ajax引擎对象
2)为Ajax引擎对象绑定监听(监听服务器已将数据响应给引擎)
3)绑定提交地址
4)发送请求
5)接受响应数据
【练习题目】:在页面中添加一个按钮,点击发送ajax请求。
开发步骤:
|
【第一步】创建Web工程:day08
注意:选择servlet2.5或以上版本,编译jdk选大于5的,比如6或7的。
【第二步】新加ajax.jsp页面,编写代码实现发送请求
静态html代码 <body> <input type="button" value="异步请求服务器" οnclick="fn1()"><span id="span1"></span><br> </body> |
编写JS实现JS原生ajax功能 function fn1() { //发送异步请求 //1.创建ajax引擎对象----所有操作都是由ajax引擎完成 var xmlHttp = new XMLHttpRequest(); //2.为引擎对象绑定监听事件 xmlHttp.onreadystatechange = function() { //当状态变化时处理的事情 if (xmlHttp.readyState == 4 && xmlHttp.status == 200) { //5.接收响应信息 var data = xmlHttp.responseText; //alert(data); document.getElementById("span1").innerHTML=data; } } //3.绑定服务器地址 //第一个参数:请求方式GET/POST //第二个参数:后台服务器地址 //第三个参数:是否是异步 true--异步 false--同步 xmlHttp.open("GET", "${pageContext.request.contextPath}/ajaxServlet?username=zhangsan", true); //4.发送请求 xmlHttp.send(); } |
注意:接收响应信息应该在监听事件中完成,并且只有当readyState为4(即请求已处理完毕,响应已准备就绪),并且status为200(正常响应)时,方可处理响应信息。
【第三步】编写Servlet处理异步请求
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //获取用户名 String name = request.getParameter("username"); response.getWriter().write(Math.random()+"-" + name); } |
【第四步】测试
发布项目并访问:http://localhost:8080/Day08/ajax.jsp
点击按钮,异步请求从后台服务器返回一个随机数和传递的参数值。
【练习扩展】对比异步与同步的区别
异步与同步的主要区别是:同步必须等待后台响应结束,页面才可以进行其他操作,出现卡死状态。而异步请求,页面不受服务器响应影响,即使服务器未发回响应,客户端仍然可以做其他操作。为了对比两者的不同,现在页面中添加两个按钮,分别实现同步发送请求和测试点击情况。
1.ajax.jsp页面中
<input type="button" value="同步请求服务器" οnclick="fn2()"><span id="span2"></span><br> <input type="button" value="测试" οnclick="alert('可以点击')"> |
编写fn2函数
function fn2() { //发送同步请求 //1.创建ajax引擎对象----所有操作都是由ajax引擎完成 var xmlHttp = new XMLHttpRequest(); //2.为引擎对象绑定监听事件 xmlHttp.onreadystatechange = function() { //当状态变化时处理的事情 if (xmlHttp.readyState == 4 && xmlHttp.status == 200) { //5.接收响应信息 var data = xmlHttp.responseText; //alert(data); document.getElementById("span2").innerHTML=data; } } //3.绑定服务器地址 //第一个参数:请求方式GET/POST //第二个参数:后台服务器地址 //第三个参数:是否是异步 true--异步 false--同步
false); //4.发送请求 xmlHttp.send(); } |
2.在AjaxServlet中使用线程的sleep方法,模拟服务器响应一段时间
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub //response.getWriter().write("zhangsan"); try {
} catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } //获取用户名 String name = request.getParameter("username"); response.getWriter().write(Math.random()+"-" + name); } |
3.页面效果对比:
点击 异步请求服务器 按钮,则在后台未响应回客户端之前仍然可以点击 测试 按钮,但点击同步请求服务器 按钮,则在后台未响应回客户端之前无法点击 测试 按钮。
注意:在JS原生Ajax中,也可以指定 如果是post提交
在发送请求之前设置一个头
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
总结:
所用异步访问都是ajax引擎
1.3 Json数据格式(重要)
1.3.1 json作用
json是一种与语言无关的数据交换的格式,其主要作用:
1)使用ajax进行前后台数据交换
2)移动端与服务端的数据交换
1.3.2 Json的格式与解析
json有两种格式:
1)对象格式:{"key1":obj,"key2":obj,"key3":obj...}
例如:user对象 用json数据格式表示
{"username":"zhangsan","age":28,"password":"123","addr":"北京"}
2)数组/集合格式:[obj,obj,obj...]
List<Product> 用json数据格式表示
[{"pid":"10","pname":"小米4C"},{},{}]
注意:对象格式和数组格式可以互相嵌套
注意:json的key是字符串 json的value是Object
json的解析:
json是js的原生内容,也就意味着js可以直接取出json对象中的数据
【Json练习一】使用对象格式保存Person对象
<script language="JavaScript"> //使用json的对象格式 var user={"firstname":"张","lastname":"三丰","age":100};
//js直接可以解析
alert(user.lastname+"----" +user.age); </script> |
【Json练习二】使用对象格式保存Person集合对象
<script language="JavaScript"> //json的数组/集合格式 var users = [ {"firstname":"张","lastname":"三丰","age":100}, {"firstname":"李","lastname":"四","age":25}, {"firstname":"王","lastname":"五","age":42} ]; alert(users[1].firstname+"---"+users[2].lastname); </script> |
其余案例请见源码day08/WebContent/json下的json01.html-json05.html。
1.3.3 Json的转换插件
通常在开发过程中,服务器端经过处理的数据为对象或者集合等类型,而返回页面时又需要将数据转换成json格式。如果这个过程完全手动拼接json字符串,则大大降低开发效率。因此,出现很多json转换的插件,主要目的就是将java的对象或集合转成json形式字符串。开发人员只要知道如果调用API即可。
常用的json转换工具有如下几种:
jsonlib:
Gson:google
fastjson:阿里巴巴
以上几种工具的具体使用步骤基本一致,分为以下几步:
第一步:引入jar包。
第二步:调用相应的API方法,实现将Java对象或集合转成Json字符串。具体API方法则在后面的案例中详细讲解。
1.4 Jquery的Ajax技术(重点)
jquery是一个优秀的js框架,自然对js原生的ajax进行了封装,封装后的ajax的操作方法更简洁,功能更强大,与ajax操作相关的jquery方法有如下几种,但开发中经常使用的有三种
- $.get(url, [data], [callback], [type])
- $.post(url, [data], [callback], [type])
其中:
url:代表请求的服务器端地址
data:代表请求服务器端的数据(可以是key=value形式也可以是json格式)
callback:表示服务器端成功响应所触发的函数(只有正常成功返回才执行)
type:表示服务器端返回的数据类型(jquery会根据指定的类型自动类型转换)
常用的返回类型:text、json、html等。
- $.ajax( { option1:value1,option2:value2... } ); ---- 以后在掌握
常用的option有如下:
async:是否异步,默认是true代表异步
data:发送到服务器的参数,建议使用json格式
dataType:服务器端返回的数据类型,常用text和json
success:成功响应执行的函数,对应的类型是function类型
type:请求方式,POST/GET
url:请求服务器端地址
1.5 实例Demo
1.5.1 注册时异步校验用户名是否可用
【功能描述】:在之前的项目中,有注册模块。一般在用户注册时,在填写用户名并文本框失去光标时,应该马上知道该用户名是否可用。该功能可以使用ajax的异步请求方法实现。具体步骤如下:
步骤一:创建WEB工程。在本案例中,为节约时间,我们使用之前的day07项目下的注册模块。
步骤二:在regist.jsp中添加异步请求
<script type="text/javascript"> $(function(){ //为文本框注册blur事件 $("#username").blur(function(){ //1.获取文本框中输入的内容 var usernameValue = $("#username").val();//this.value //$(this).val()
//2.发送ajax请求 $.post( "${pageContext.request.contextPath}/checkUsername", {"username":usernameValue}, function(data){
var isExist = data.isExist; var usernameInfo=""; if(isExist)//用户存在 ,用户名不可以使用 { usernameInfo="该用户名已被占用"; $("#usernameInfo").css("color","red");
}else{ usernameInfo="该用户名可以使用"; $("#usernameInfo").css("color","green"); }
$("#usernameInfo").html(usernameInfo);
}, "json" ) }) }) </script> |
步骤三:添加后台服务器端处理的Servlet
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1.获取用户名 String username = request.getParameter("username"); //2.调用service方法,验证用户名是否存在 UserService service = new UserService(); boolean isExist = service.checkUsername(username); //自己手动拼接json字符串 response.getWriter().write("{\"isExist\":"+isExist+"}"); } |
步骤四:Service层和Dao层
UserService.java中
public boolean checkUsername(String username) { UserDao dao = new UserDao(); Long count = 0L; try { count = dao.checkUsername(username); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } return count>0?true:false; } |
UserDao.java中
public Long checkUsername(String username) throws SQLException { QueryRunner runner = new QueryRunner(DataSourceUtils.getDataSource()); String sql ="select count(*) from user where username=?"; Long row = (Long)runner.query(sql, new ScalarHandler(), username); return row; } |
若实现以上步骤,在项目部署完毕,则注册模块即可实现实时验证用户名是否可用。
1.5.2 实现站内搜索功能
【功能描述】:在我们的贯穿项目中,首页有个站内搜索功能,即当在搜索栏中搜索内容时,搜索栏下方实时弹出当前商城下所有相关产品名称。实现步骤如下:
步骤一:修改商城头部页面header.jsp,使其满足样式需要,并为搜索框添加onkeyup事件
<form class="navbar-form navbar-right" role="search"> <div class="form-group" style="position: relative"> <input id="search" type="text" class="form-control" placeholder="Search" οnkeyup="searchWord(this)"> <div id="showDiv" style="display:none;position: absolute;z-index:1000; background-color:#fff; 196px; border:1px solid #ccc"> </div> </div> <button type="submit" class="btn btn-default">Submit</button> </form> |
步骤二:编写事件处理函数
function searchWord(obj) { //1.当键盘抬起时,获取输入框中的内容 // alert(obj.value); var word = $(obj).val(); //2.ajax请求发送服务器,模糊查询关键字List<Product> List<String> $.post( "${pageContext.request.contextPath}/searchWord",//地址 {"word":word}, function(data){ if(data.length>0){ var content=""; //3.解析数据,显示到showDiv中 for(var i=0;i<data.length;i++) { content+="<div style='padding:5px;cursor:pointer' οnmοuseοver='overfn(this)' οnmοuseοut='outfn(this)' οnclick='clickDiv(this)'>"+data[i]+"</div>"; }
$("#showDiv").html(content); $("#showDiv").css("display","block"); }
"json" );
}
function overfn(obj) { $(obj).css("background-color","#ccc"); } function outfn(obj) { $(obj).css("background-color","#fff"); } function clickDiv(obj) { $("#search").val($(obj).html()); $("#showDiv").css("display","none"); } |
步骤三:添加服务器端处理的Servlet代码
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub //获取关键词 String word = request.getParameter("word"); ProductService service = new ProductService(); List<Object> productList = service.searchWord(word);
//需要将集合转成json格式的字符串 //[{"pname":"小米","shop_price":1988,.....},{}] //jsonlib /*JSONArray array = JSONArray.fromObject(productList); String json = array.toString();*/ //System.out.println(json);
//Gson Gson gson = new Gson(); String json = gson.toJson(productList); //["小米","华为","".......] response.setContentType("text/html;charset=UTF-8"); response.getWriter().write(json); } |
在该步骤中,使用了jsonlib和Gson两种方式将java对象进行转换成json字符串,从两者对比可以看出,jsonlib方式较繁琐,而Gson工具处理则更加简洁。对于fastjson的用法,同学们可以自行学习。
第四步骤:编写Service层和Dao层代码(此处略,详细请见源码)
第五步骤:测试。
1.6 总结
本章主要讲解Web开发中常用技术之一——Ajax异步刷新技术。希望通过本文档配合视频和源码,能使所有同学掌握该技术的关键内容。
代码示例
js代码:
-
<%@ page language="java" contentType="text/html; charset=UTF-8"
-
pageEncoding="UTF-8"%>
-
<!DOCTYPE>
-
<html>
-
<head>
-
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
-
<title>ajax</title>
-
<script type="text/javascript">
-
function fn1() {
-
//获取要携带的参数
-
var uname = document.getElementById("uname").value;
-
var upass = document.getElementById("upass").value;
-
//发送异步请求
-
//1.创建ajax引擎对象----所有操作都是由ajax引擎完成
-
var xmlHttp; //ajax请求状态码0
-
if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari
-
xmlhttp = new XMLHttpRequest();
-
} else {// code for IE6, IE5
-
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
-
}
-
//2.为引擎对象绑定监听事件 (设置回调函数)
-
xmlhttp.onreadystatechange = function(){
-
//等待服务器响应
-
if(xmlhttp.readyState==4){
-
//当请求状态为4时,说明请求完成
-
if(xmlhttp.status==200){
-
//判断服务器响应状态吗是否正常
-
//取出响应的数据
-
var result = xmlhttp.responseText;
-
//将数据通过JS添加到页面
-
document.getElementById("result").innerHTML=result;
-
}
-
}
-
}
-
//3.绑定服务器地址
-
//第一个参数:请求方式GET/POST
-
//第二个参数:后台服务器地址
-
//第三个参数:是否是异步 true--异步 false--同步
-
xmlhttp.open("GET", "ajax?uname="+uname+"&upass="+upass, true);
-
//4.发送请求
-
xmlhttp.send();
-
//ajax请求状态码1,2,3,4
-
//发送请求之后,执行JS
-
document.getElementById("r").innerHTML="这里是测试的内容";
-
}
-
function fn2() {
-
//获取要携带的参数
-
var uname = document.getElementById("uname").value;
-
var upass = document.getElementById("upass").value;
-
//发送异步请求
-
//1.创建ajax引擎对象----所有操作都是由ajax引擎完成
-
var xmlHttp; //ajax请求状态码0
-
if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari
-
xmlhttp = new XMLHttpRequest();
-
} else {// code for IE6, IE5
-
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
-
}
-
//2.为引擎对象绑定监听事件 (设置回调函数)
-
xmlhttp.onreadystatechange = function(){
-
//等待服务器响应
-
if(xmlhttp.readyState==4){
-
//当请求状态为4时,说明请求完成
-
if(xmlhttp.status==200){
-
//判断服务器响应状态吗是否正常
-
//取出响应的数据
-
var result = xmlhttp.responseText;
-
//将数据通过JS添加到页面
-
document.getElementById("result").innerHTML=result;
-
}
-
}
-
}
-
//3.绑定服务器地址
-
//第一个参数:请求方式GET/POST
-
//第二个参数:后台服务器地址
-
//第三个参数:是否是异步 true--异步 false--同步
-
xmlhttp.open("POST", "ajax", true);
-
//设置Content-type
-
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
-
//4.发送请求
-
xmlhttp.send("uname="+uname+"&upass="+upass);
-
//ajax请求状态码1,2,3,4
-
//发送请求之后,执行JS
-
document.getElementById("r").innerHTML="这里是测试的内容";
-
}
-
</script>
-
</head>
-
<body>
-
<form action="ajax" method="post">
-
<input type="text" id="uname" name="uname" placeholder="请输入用户">
-
<input type="text" id="upass" name="upass" placeholder="请输入密码">
-
<input type="button" onclick="fn1()" value="提交GET" />
-
<input type="button" onclick="fn2()" value="提交POST" />
-
</form>
-
<span id="r"></span>
-
<br/>
-
<span id="result">
-
</span>
-
</body>
-
</html>
后端:
-
package com.igeek.servlet;
-
import java.io.IOException;
-
import java.io.PrintWriter;
-
import javax.servlet.ServletException;
-
import javax.servlet.http.HttpServlet;
-
import javax.servlet.http.HttpServletRequest;
-
import javax.servlet.http.HttpServletResponse;
-
/**
-
* Servlet implementation class AjaxServlet
-
*/
-
public class AjaxServlet extends HttpServlet {
-
private static final long serialVersionUID = 1L;
-
public AjaxServlet() {
-
super();
-
}
-
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
-
// try {
-
// Thread.sleep(3000);
-
// } catch (InterruptedException e) {
-
// e.printStackTrace();
-
// }
-
//取出请求参数
-
String name = request.getParameter("uname");
-
System.out.println(name);
-
String pass = request.getParameter("upass");
-
System.out.println(pass);
-
//响应客户端
-
//response.sendRedirect("index.jsp");
-
PrintWriter writer = response.getWriter();
-
writer.write("abc");
-
writer.close();
-
}
-
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
-
request.setCharacterEncoding("utf-8");
-
doGet(request, response);
-
}
-
}