Ajax&jQuery
1.Ajax
Asynchronous JavaScript and XML(异步的 JavaScript 和 XML),不是新的编程语言,而是一种使用现有标准的新方法。
AJAX 最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新网页上的局部内容。
AJAX 不需要任何浏览器插件,但需要用户允许JavaScript在浏览器上执行。
1.1XMLHttpRequest对象
XMLHttpRequest对象用于和服务器交换数据。
- 创建XMLHttpRequest对象
var xmlhttp;
if (window.XMLHttpRequest){
// IE7+, Firefox, Chrome, Opera, Safari 浏览器执行代码
xmlhttp=new XMLHttpRequest();
}else{
// IE6, IE5 浏览器执行代码
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
XMLHttpRequest的常用方法:
-
open(method,url,async)
XMLHttpRequest.open(method,url,async):规定请求的类型、URL 以及是否异步处理请求。
method:"GET":get请求;"POST":post请求
url:"/Demo2/AjaxDemoServlet?id=1",请求地址路径
async:true:异步请求;false:同步请求 -
send(string)
XMLHttpRequest.send(String):将请求发送到服务器。
String仅针对post请求,get请求不能携带String。
-
setRequestHeader(header,value)
xmlHttpRequest.setRequestHeader(header,value):向请求添加HTTP头。
如果需要像 HTML 表单那样 POST 数据,请使用 setRequestHeader() 来添加 HTTP 头。然后在 send() 方法中规定您希望发送的数据:
xmlHttpRequest.setRequestHeader("Content-type","application/x-www-form-urlencoded"); xmlHttpRequest.send("id=1&name=wang");
1.2服务器响应
使用 XMLHttpRequest 对象的 responseText 或 responseXML 属性来获取服务器的响应。
- responseText:获得字符串形式的响应数据。
- responseXML:获得 XML 形式的响应数据。
1.3onreadystatechange事件
用于执行一些基于响应的任务,当readyState改变时,就会触发onreadystatechange事件。
下面是 XMLHttpRequest 对象的三个重要的属性:
当 readyState 等于 4 且状态为 200 时,表示响应已就绪。
1.4Ajax执行Get请求
- 不获取响应数据
<script>
function getDemo() {
//1.创建XMLHttpRequest对象
var xmlHttpRequest=new XMLHttpRequest();
//2.向服务器发送Get请求
xmlHttpRequest.open("GET","/Demo2/AjaxDemoServlet?id=1",true);
//将请求发送到服务器
xmlHttpRequest.send();
}
</script>
- 获取响应数据
<script>
function getDemo() {
var xmlHttpRequest=new XMLHttpRequest();
//3.注册监听,以便获取响应数据
xmlHttpRequest.onreadystatechange=function () { if(xmlHttpRequest.readyState==4&&xmlHttpRequest.status==200){
alert(xmlHttpRequest.responseText);
}
}
xmlHttpRequest.open("GET","/Demo2/AjaxDemoServlet?id=1",true);
xmlHttpRequest.send();
}
响应数据:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("收到一个get请求,id为"+request.getParameter("id"));
response.setContentType("text/html;charset=utf-8");
response.getWriter().write("收到了get请求");
}
1.5Ajax执行Post请求
- 不获取响应数据
function postDemo() {
//1.创建XMLHttpRequest对象
var xmlHttpRequest=new XMLHttpRequest();
//2.向服务器发送Post请求
xmlHttpRequest.open("POST","/Demo2/AjaxDemoServlet",true);
//向请求添加添加http头,表示像html表单那样post数据
xmlHttpRequest.setRequestHeader("Content-type","application/x-www-form-urlencoded");
//将请求发送到服务器
xmlHttpRequest.send("id=1&name=wang");
}
- 获取响应数据
function postDemo() {
var xmlHttpRequest=new XMLHttpRequest();
//获取响应数据
xmlHttpRequest.onreadystatechange=function(){
if(xmlHttpRequest.readyState==4&&xmlHttpRequest.status==200){
alert(xmlHttpRequest.responseText);
}
}
xmlHttpRequest.open("POST","/Demo2/AjaxDemoServlet",true);
xmlHttpRequest.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlHttpRequest.send("id=1&name=wang");
}
响应数据:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("收到一个post请求,id为"+request.getParameter("id")+",name为"+request.getParameter("name"));
response.setContentType("text/html;charset=utf-8");
response.getWriter().write("收到了post请求");
}
1.6案例:Ajax校验用户名是否可用
- register_Ajax.jsp
<head>
<title>用户注册页面</title>
<script>
function checkUsername() {
var xmlHttpRequest=new XMLHttpRequest();
var username=document.getElementById("name").value;
xmlHttpRequest.onreadystatechange=function () {
if(xmlHttpRequest.readyState==4&&xmlHttpRequest.status==200){
var data=xmlHttpRequest.responseText;
if(data==0){
document.getElementById("span1").innerHTML="<font color='red'>用户名已被占用</font>"
}else if(data==1){
document.getElementById("span1").innerHTML="<font color='green'>用户名可用</font>"
}
}
}
xmlHttpRequest.open("GET","/Demo2/CheckUsernameServlet?username="+username,true);
xmlHttpRequest.send();
}
</script>
</head>
<body>
<form action="RegisterServlet" method="post">
请输入用户名:<input type="text" name="username" id="name" onblur="checkUsername()"/><span id="span1"></span><br/>
请输入密码:<input type="text" name="password"/><br/>
<input type="submit" value="注册"/>
</form>
</body>
注意:获取id为name的元素的值要用document.getElementById("name").value,而不是document.getElementById("name")。
用document.getElementById("name")获取的是元素,而不是值,如下图:
- CheckUsernameServlet
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("username");
response.setContentType("text/html;charset=utf-8");
if(username.equals("COCO")){
// response.getWriter().write(0);
response.getWriter().print(0);
}else {
//response.getWriter().write(1);
response.getWriter().print(1);
}
}
注意:这里返回int只能用print或println,write只能写字符型,即char,而且数字传到前端会产生乱码,如下:
- write和print方法比较:
write():仅支持输出字符类型数据,字符、字符数组、字符串等;
print():可以将各种类型(包括Object)的数据通过默认编码转换成bytes字节形式,这些字节都通过write(int c)方法被输出。
2.jQuery
jQuery是一个JavaScript库,可以极大简化Javascript编程。
2.1安装jQuery
- 下载后安装jQuery
将jquery-1.11.3.min.js拷贝到工程目录中,如web/js/jquery-1.11.3.min.js,然后在页面上引用:
<script src="js/jquery-1.11.3.min.js"></script>
是否疑惑为什么没有在 <script> 标签中使用 type="text/javascript"?因为在HTML5中,不必那样做了。JavaScript 是HTML5以及所有现代浏览器中的默认脚本语言。
- CDN引用
如果不希望下载并存放 jQuery,那么也可以通过 CDN(内容分发网络) 引用它。Staticfile CDN、百度、又拍云、新浪、谷歌和微软的服务器都存有 jQuery 。
百度CDN:
<script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js">
又拍云CDN:
<script src="https://upcdn.b0.upaiyun.com/libs/jquery/jquery-2.0.2.min.js">
2.2jQuery选择器
-
元素选择器
基于元素名选取元素。
$("button"):在页面获取所有的
<button>
元素。 -
id选择器
通过元素的id属性选取指定的元素。
$("#id2"):获取id为id2的元素。
-
类选择器
通过指定的class属性查找元素。
$(".test"):查找带有class="test"属性的元素。
2.3jQuery设置内容
-
text()
设置或返回所选元素的文本内容,两个标签中写值,如
<textarea id="id3"></textarea>
-
html()
设置或返回元素的内容(包括html标记)。
-
val()
设置或返回表单字段的值,用于元素里面有value属性的。
2.4jQuery常用方法
2.4.1load()方法
load()方法从服务器加载数据,并把返回的数据放入被选元素中。
语法:
$(selector).load(URL,data,callback);
/*
必需的 URL 参数规定您希望加载的 URL。
可选的 data 参数规定与请求一同发送的查询字符串键/值对集合。
可选的 callback 参数是 load() 方法完成后所执行的函数名称。
*/
2.4.1.1load()方法演示
- jQueryServlet
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("收到一个请求");
response.setContentType("text/html;charset=utf-8");
response.getWriter().write("执行load方法");
}
- jQueryDemo.jsp
<head>
<title>Title</title>
<script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
<script>
function loadDemo() {
$("#id2").load("/Demo2/jQueryServlet",function (responseTxt,statusTxt,xhr){
$("#id2").val(responseTxt);//将响应回的数据放入到id为id2的元素中
});
}
</script>
</head>
<body>
<a href="" onclick="loadDemo()" id="id1">使用jQuery执行load方法</a><br/>
<input type="button" value="使用jQuery执行load方法" onclick="loadDemo()"/>
<input type="text" id="id2"/>
</body>
注意:
如果用超链接:
<a href="" onclick="loadDemo()" id="id1">使用jQuery执行load方法</a><br/>
响应回的数据会在id2中一闪而过,原因是有两次刷新,先走 onClick的方法,取到数据回来之后,赋值显示。接着走 href=""的路径,但是这个属性没有给值,所以会把当前的页面重新再刷新一次,导致看不见值。
2.4.2get()方法
$.get() 方法通过 HTTP GET 请求从服务器上请求数据。
语法:
$.get(url,callback);
必需的url参数规定希望请求的URL。
可选的callback参数是请求成功后所执行的函数名。
2.4.2.1get()方法演示
<script>
$(document).ready(function () {
$("button").click(function () {//即点击button后执行get请求
$.get("/Demo2/jQueryServlet",function (data,status) {
$("#id2").val(data);//将返回的数据填入id2
$("#id3").text(data);
});
});
})
</script>
<body>
<button>演示get</button><br/>
<input type="text" id="id2"/>
<textarea id="id3"></textarea>
</body>
2.4.3post()方法
$.post() 方法通过 HTTP POST 请求从服务器上请求数据。
语法:
$.post(url,data,callback);
必需的url参数规定您希望请求的url。
可选的data参数规定连同请求发送的数据。
可选的callback参数是请求成功后所执行的函数名。
2.4.3.1post()方法演示
<script>
$(document).ready(function () {
$("button").click(function () {
$.post("/Demo2/jQueryServlet",{name:"wanger",age:19},
function (data,status) {
$("#id2").val(data+"\"+status);
});
});
})
</script>
<body>
<button>演示post</button><br/>
<input type="text" id="id2"/>
</body>
2.5案例1:jQuery校验用户名是否可用
- register_jQuery.jsp
<script>
function checkUsername() {
//var username=document.getElementById("name").value;
var username=$("#name").val();//以jQuery方式获取用户名
$.post("/Demo2/jQueryServlet",{name:username},function (data,status) {
if(data==0){
$("#span1").html("<font color='red'>用户名已被占用</font>");
}else{
$("#span1").html("<font color='green'>用户名可用</font>");
}
})
}
</script>
<body>
<form action="RegisterServlet" method="post">
请输入用户名:<input type="text" name="username" id="name" onblur="checkUsername()"/><span id="span1"></span><br/>
请输入密码:<input type="text" name="password"/><br/>
<input type="submit" value="注册"/>
</form>
</body>
2.6案例2:jQuery实现仿百度提示
效果如下:
- HeimaSearch.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>黑马搜索</title>
<script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
<script>
/*文档就绪代码:$(document).ready(function () {})可简写为$(function(){})*/
$(function () {
$("#search").keyup(function () {
//var search=$("#search").val();
var search=$(this).val();//this即为执行此方法的对象:$("#search");
if(search!=""){//当输入框不为空时才发送请求
$.post("/StuSysMvc/HeimaSearchServlet",{searchValue:search},function(data,status){
if(data!=""){
$("#div01").show();//当返回值不为空时才展示搜索提示框
$("#div01").html(data);
}else{
$("#div01").hide();//非第一次时返回值为空时隐藏搜索提示框
}
})
}else{
$("#div01").hide();//删除搜索内容后要隐藏搜索提示框
}
})
})
</script>
</head>
<body>
<center >
<br/><br/><br/><br/><br/><br/>
<h2>Heima黑马</h2>
<input type="text" name="search" id="search" onkeyup="initSearch()" style=" 600px ; height: 55px ;font-size: 20px;"/>
<input type="button" value="黑马一下" style="height: 55px ; 100px ; ">
<div id="div01" style="position:relative; left : -52px; 600px; border: 1px solid blue; display: none;"></div>
<%--
display:none搜索框默认不显示;
div01这个div不指定高度,而是根据返回的list.jsp中的数据动态调整。
--%>
</center>
</body>
</html>
- HeimaSearchServlet
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
String searchValue = request.getParameter("searchValue");
System.out.println("收到请求:"+searchValue);
StudentService studentService=new StudentServiceImpl();
List<Student> list=studentService.initSearch(searchValue);//dao层可设置默认最多只查找10条
request.setAttribute("list",list);
request.getRequestDispatcher("list.jsp").forward(request,response);
//响应list.jsp页面给请求者。请求:浏览器请求,浏览器看到这个jsp页面
}
-
list.jsp
在list.jsp页面遍历list,HeimaSearchServlet将list.jsp返回给请求者。
<table width="100%"><%--设置此table和div同宽,使结果左对齐--%>
<c:forEach var="stu" items="${list}">
<tr>
<td>${stu.sname}</td>
</tr>
</c:forEach>
</table>
2.7案例3:jQuery实现省市联动
2.7.1数据库准备
准备两张表:province和city,给city表的c_pid字段添加外键约束指向province表的唯一索引:主键pid。
2.7.2使用xml传输数据
-
依赖jar包
-
proCity_xml.jsp
<script>
$(function () {
$("#province").change(function () {
var choice=$(this).val();
if(choice!=""){
$.post("/StuSysMvc/ProCityServlet",{province:choice},function (data,status) {
$("#city").html("<option value=''>--请选择--</option>");//清空city中的option
//从data数据里找出所有的city,然后遍历所有的city,每遍历一个city就执行一次function方法
/*<list>
<city>
<cid>1<id>
<cname>郑州</cname>
<cPid>1</cPid>
</city>
......
</list>*/
$(data).find("city").each(function () {
var cid=$(this).children("cid").text();
var cname=$(this).children("cname").text();
$("#city").append("<option value='"+cid+"'>"+cname+"</option>");
})
})
}
});
});
</script>
</head>
<body>
省份:<select name="province" id="province">
<option value="">--请选择--</option>
<option value="1">河南</option>
<option value="2">广东</option>
</select>
城市:<select name="city" id="city">
<option value="">--请选择--</option>
</select>
</body>
- ProCityServlet
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Integer pid = Integer.parseInt(request.getParameter("province"));
StudentService studentService=new StudentServiceImpl();
List<City> list = studentService.findCityByPid(pid);
//返回数据
//可以像仿百度提示那样返回html,但最好采用返回xml或json
//1.返回xml
XStream xStream=new XStream();
//xStream.useAttributeFor(City.class,"cid");//将cid设置为city的属性,写在设置别名前后均可
xStream.alias("city",City.class);
//xStream.useAttributeFor(City.class,"cid");
String s = xStream.toXML(list);
response.setContentType("text/xml;charset=utf-8");//注意这里是xml
response.getWriter().write(s);
}
xml数据如下:
修改别名:将com.itheima.entity.City改为city,并将cid设置为city的属性:
2.7.3使用json传输数据
-
依赖jar包:
-
proCity_json.jsp
<script>
$(function () {
$("#province").change(function () {
var choice=$(this).val();
if(choice!=""){
$.post("/StuSysMvc/ProCityServlet",{province:choice},function (data,status) {
$("#city").html("<option value=''>--请选择--</option>");
/*data:
[
{
"cPid":2,
"cid":5,
"cname":"广州"
},
...
]
*/
//先遍历,再追加
$(data).each(function (index,c) {//index:索引;c:遍历到的元素
$("#city").append("<option value='"+c.cid+"'>"+c.cname+"</option>")
})
},"json")//最后一个参数为dataType,指定数据类型为json,默认智能判断(xml,json,script,html),但json数据不能识别出来,需要声明一下
}
});
});
</script>
- ProCityServlet
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Integer pid = Integer.parseInt(request.getParameter("province"));
StudentService studentService=new StudentServiceImpl();
List<City> list = studentService.findCityByPid(pid);
//返回数据
//2.返回Json
JSONArray jsonArray = JSONArray.fromObject(list);
/*
JSONArray:转化为json数组:[{"cPid":2,"cid":5,"cname":"广州"},{"cPid":2,"cid":6,"cname":"东莞"},{"cPid":2,"cid":7,"cname":"深圳"},{"cPid":2,"cid":8,"cname":"江门"}]
JSONObject:转化为接送数据:{"cPid":2,"cid":5,"cname":"广州"}
*/
String s = jsonArray.toString();
System.out.println(s);
response.setContentType("text/html;charset=utf-8");
response.getWriter().write(s);*/
}