Ajax和jQuery
一、Ajax
1、Ajax概述
- ajax:Asynchronous JavaScript and XML(Asynchronous:异步的 JavaScript 和 XML)。
- Asynchronous: 异步的意思
- JavaScript:javascript脚本,在浏览器中执行
- xml : 是一种数据格式
- ajax是一种做局部刷新的方法,不是一种语言。 是浏览器客户端上的前端技术,是多个技术联合实现的产物。
- ajax包含的技术主要有javascript,dom,css,,xml等等。 核心是javascript 和 xml 。
- javascript:负责创建异步对象, 发送请求, 更新页面的dom对象。
- xml: 网络中的传输的数据格式。 使用json替换了xml 。
- ajax请求需要服务器端的数据。
- 最大的优势:无刷新获取数据。
2、XML 简介
- XML 可扩展标记语言。
- XML 被设计用来传输和存储数据。
- XML 和 HTML 类似,不同的是 HTML 中都是预定义标签,而 XML 中没有预定义标签, 全都是自定义标签,用来表示一些数据
比如说:一个学生数据: name = “孙悟空” ; age = 18 ; gender = “男”
- 用 XML 表示:
<student>
<name>孙悟空</name>
<age>18</age>
<gender>男</gender>
</student>
- 用 JSON 表示
{"name":"孙悟空","age":18,"gender":"男"}
3、AJAX的特点
(1) AJAX 的优点:
- 可以无需刷新页面而与服务器端进行通信。
- 允许根据用户事件来更新部分页面内容。
(2) AJAX 的缺点:
- 没有浏览历史,不能回退
- 存在跨域问题(同源)
- SEO 不友好(Search Engine Optimization 搜索引擎优化)
4、 AJAX 的使用
(1) 核心对象
XMLHttpRequest,AJAX 的所有操作都是通过该对象进行的
(2) 使用步骤:
- 创建 XMLHttpRequest 对象
var xhr = new XMLHttpRequest();
- 设置请求信息(初始异步请求对象)
//.open(method, url,同步异步请求(默认是true,异步请求));
xmlHttp.open("get", "loginServletname=zs&pwd=123",true);
//可以设置请求头,一般不设置
- 发送请求
xmlHttp.send(body) //get 请求不传 body 参数,只有 post 请求使用
//获取服务器端返回的数据, 使用异步对象的属性 responseText.
//xmlHttp.responseText
- 接收响应
var xmlHttp = new XMLHttpRequest();
xmlHttp.onreadystatechange= function(){
处理请求的状态变化。
if(xmlHttp.readyState == 4 && xmlHttp.status== 200 ){
//可以处理服务器端的数据,更新当前页面
var data = xmlHttp.responseText;
document.getElementById("name").value= data;
}
}
(3) 解决 IE 缓存问题
- 问题:在一些浏览器中(IE),由于缓存机制的存在,ajax 只会发送的第一次请求,剩 余多次请求不会在发送给浏览器而是直接加载缓存中的数据。
- 解决方式:浏览器的缓存是根据 url 地址来记录的,所以我们只需要修改 url 地址 即可避免缓存问题
xhr.open("get","/testAJAX?t="+Date.now());
(4)AJAX 请求状态
- xhr.readyState 可以用来查看请求当前的状态
- 0: 表示 XMLHttpRequest 实例已经生成,但是 open()方法还没有被调用。
- 1: 表示 send()方法还没有被调用,仍然可以使用 setRequestHeader(),设定 HTTP请求的头信息。
- 2: 表示 send()方法已经执行,并且头信息和状态码已经收到
- 3: 表示正在接收服务器传来的 body 部分的数据。
- 4: 表示服务器数据已经完全接收,或者本次接收已经失败了
在4的时候,开发人员做什么更新当前页面。
- 异步对象的status属性,表示网络请求的状况: 200, 404, 500, 当status==200时,表示网络请求是成功的。
5、Ajax实例
(1)计算BMI
①全局刷新计算BMI
需求:计算某个用户的 BMI。 用户在 jsp 输入自己的身高,体重;servlet 中计算 BMI,并显 示 BMI 的计算结果和建议。
package com.cooler.controller;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author CoolEr
* @create 2022/2/23
*/
public class BmiServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1、接收请求参数
String name = request.getParameter("name");
String height = request.getParameter("h");
String weight = request.getParameter("w");
//2、计算BMI= 体重/身高的平方
float h = Float.valueOf(height);
float w = Float.valueOf(weight);
float bmi = w / (h * h);
//3、判断BMI的范围
String msg = "";
if(bmi <= 18.5){
msg = "您比较瘦";
}else if(bmi > 18.5 && bmi <= 23.9){
msg = "您的BMI是正常的";
}else if(bmi > 24 && bmi <= 27){
msg = "您的身体比较胖";
}else{
msg = "您的身体属于肥胖";
}
msg = "您好!" + name + "您的BMI值是" + bmi + "," + msg;
System.out.println(msg);
request.setAttribute("msg",msg);
request.getRequestDispatcher("/result.jsp").forward(request,response);
}
}
<%--
Created by IntelliJ IDEA.
User: dell
Date: 2022/2/23
Time: 14:58
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>结果页面</title>
</head>
<body>
<p>显示BMI结果</p>
<h3>${msg}</h3>
</body>
</html>
<%--
Created by IntelliJ IDEA.
User: dell
Date: 2022/2/23
Time: 14:33
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>全局刷新</title>
</head>
<body>
<p>全局刷新计算BMI</p>
<form action="bmiServlet" method="get">
姓名:<input type="text" name="name"><br>
体重(KG):<input type="text" name="w"><br>
身高(M):<input type="text" name="h"><br>
<input type="submit" value="提交">
</form>
</body>
</html>
②ajax局部刷新计算BMI
//1、接收请求参数
String name = request.getParameter("name");
String height = request.getParameter("h");
String weight = request.getParameter("w");
//2、计算BMI= 体重/身高的平方
float h = Float.valueOf(height);
float w = Float.valueOf(weight);
float bmi = w / (h * h);
//3、判断BMI的范围
String msg = "";
if(bmi <= 18.5){
msg = "您比较瘦";
}else if(bmi > 18.5 && bmi <= 23.9){
msg = "您的BMI是正常的";
}else if(bmi > 24 && bmi <= 27){
msg = "您的身体比较胖";
}else{
msg = "您的身体属于肥胖";
}
msg = "您好!" + name + "您的BMI值是" + bmi + "," + msg;
System.out.println(msg);
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
out.print(msg);
<%--
Created by IntelliJ IDEA.
User: dell
Date: 2022/2/23
Time: 15:36
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>局部刷新——ajax</title>
<script type="text/javascript">
function doAjax(){
//1、创建异步对象
var xmlHTTP = new XMLHttpRequest();
//2、绑定事件
xmlHTTP.onreadystatechange = function () {
if(xmlHTTP.readyState == 4 && xmlHTTP.status == 200){
alert(xmlHTTP.responseText);
}
}
//3、初始请求对象
var name = document.getElementById("name").value;
var w = document.getElementById("w").value;
var h = document.getElementById("h").value;
var param = "name=" + name + "&w=" +w +"&h=" + h;
xmlHTTP.open("get","bmiAjax?"+param,true);
//4、发起请求
xmlHTTP.send();
}
</script>
</head>
<body>
<div>
姓名:<input type="text" id="name" /><br>
体重(KG):<input type="text" id="w" /><br>
身高(m):<input type="text" id="h" /><br>
<input type="button" value="计算bmi" οnclick="doAjax()">
</div>
</body>
</html>
- 更新dom对象
if( xmlHttp.readyState == 4 && xmlHttp.status ==200){
// alert(xmlHttp.responseText);
var data = xmlHttp.responseText;
//更新dom对象, 更新页面数据
document.getElementById("mydata").innerText = data;
}
……
<div id="mydata">等待加载数据....</div>
(2)根据省份 id 查询省份名称
需求:用户在文本框架输入省份的编号 id,在其他文本框显示省份名称
- 数据库:cooler
- 数据表:
省份信息表:
CREATE TABLE `province` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL COMMENT '省份名称',
`jiancheng` varchar(255) DEFAULT NULL COMMENT '简称',
`shenghui` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8;
城市信息表:
CREATE TABLE `city` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
`provinceid` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=17 DEFAULT CHARSET=utf8;
-
json分类:
- json对象 ,JSONObject ,这种对象的格式: 名称:值, 也可以看做是 key:value 格式。
- json数组, JSONArray, 基本格式:
- [{ name:“河北”, jiancheng:“冀”,“shenghui”:“石家庄”} , { name:“山西”, jiancheng:“晋”,“shenghui”:“太原”} ]
-
处理json的工具库: gson(google); fastjson(阿里),jackson, json-lib
-
Province p = new Province(); ObjectMapper om = new ObjectMapper();//把参数的java对象转为json格式的字符串 String json = om.writeValueAsString(p);
-
-
在js中的,可以把json格式的字符串,转为json对象, json中的key,就是json对象的属性名。
var data = xmlHttp.responseText;
//eval是执行括号中的代码, 把json字符串转为json对象
var jsonobj = eval("(" + data + ")");
①功能实现代码
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>使用json格式的数据</title>
<script type="text/javascript">
function doSearch() {
//1.创建异步对象
var xmlHttp = new XMLHttpRequest();
//2.绑定事件
xmlHttp.onreadystatechange = function() {
if( xmlHttp.readyState == 4 && xmlHttp.status == 200){
var data = xmlHttp.responseText;
//eval是执行括号中的代码, 把json字符串转为json对象
var jsonobj = eval("(" + data + ")");
//更新dom对象
callback(jsonobj);
}
}
//3.初始异步对象的请求参数
var proid = document.getElementById("proid").value;
// true :异步处理请求。 使用异步对象发起请求后,不用等待数据处理完毕,就可以执行其它的操作。
// false:同步,异步对象必须处理完成请求,从服务器端获取数据后,才能执行send之后的代码。 任意时刻只能执行一个异步请求。
xmlHttp.open("get","queryjson?proid="+proid,true);
//4.发送请求
xmlHttp.send();
}
//定义函数,处理服务器端返回的数据
function callback(json){
document.getElementById("proname").value = json.name;
document.getElementById("projiancheng").value=json.jiancheng;
document.getElementById("proshenghui").value= json.shenghui;
}
</script>
</head>
<body>
<p>ajax请求使用json格式的数据</p>
<table>
<tr>
<td>省份编号:</td>
<td><input type="text" id="proid">
<input type="button" value="搜索" οnclick="doSearch()">
</td>
</tr>
<tr>
<td>省份名称:</td>
<td><input type="text" id="proname"></td>
</tr>
<tr>
<td>省份简称:</td>
<td><input type="text" id="projiancheng"></td>
</tr>
<tr>
<td>省会名称:</td>
<td><input type="text" id="proshenghui"></td>
</tr>
</table>
</body>
</html>
package com.cooler.controller;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import com.cooler.dao.ProvinceDao;
import java.io.IOException;
import java.io.PrintWriter;
/**
* @author CoolEr
* @create 2022/2/23
*/
public class QueryProvinceServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req,
HttpServletResponse resp) throws ServletException, IOException {
//处理get请求
String strProid = req.getParameter("proid");
System.out.println("strProid:"+ strProid);
String name = "默认是无数据";
//访问dao,查询数据库
if( strProid != null && !"".equals(strProid.trim()) ){
//创建dao对象,调用它的方法
ProvinceDao dao = new ProvinceDao();
name = dao.queryProviceNameById( Integer.valueOf(strProid));
}
//使用HttpServletResponse输出数据
// servlet返回给浏览器的是 文本数据, 数据的编码是utf-8
resp.setContentType("text/html;charset=utf-8");
PrintWriter pw = resp.getWriter();
//pw.println("中国");
pw.println(name);
pw.flush();
pw.close();
}
}
package com.cooler.dao;
import com.cooler.entity.Province;
import java.sql.*;
//使用jdbc访问数据库
public class ProvinceDao {
//根据id获取名称
public String queryProviceNameById(Integer proviceId){
Connection conn = null;
PreparedStatement pst = null;
ResultSet rs = null;
String sql= "";
String url="jdbc:mysql://localhost:3306/cooler";
String username="root";
String password="3399";
String name = "";
//加载驱动
try {
Class.forName("com.mysql.cj.jdbc.Driver");
conn = DriverManager.getConnection(url,username,password);
//创建PreparedStatement
sql="select name from province where id=?";
pst = conn.prepareStatement(sql);
//设置参数值
pst.setInt(1,proviceId);
//执行sql
rs = pst.executeQuery();
//遍历rs
/*while(rs.next()){ //当你的rs中有多余一条记录时。
name = rs.getString("name");
}*/
if( rs.next()){
name =rs.getString("name");
}
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
} finally {
try{
if( rs != null){
rs.close();
}
if( pst != null){
pst.close();
}
if( conn != null){
conn.close();
}
}catch(Exception e){
e.printStackTrace();
}
}
return name;
}
//根据id获取一个完整的Province对象
public Province queryProviceById(Integer proviceId){
Connection conn = null;
PreparedStatement pst = null;
ResultSet rs = null;
String sql= "";
String url="jdbc:mysql://localhost:3306/cooler";
String username="root";
String password="3399";
Province province = null;
//加载驱动
try {
Class.forName("com.mysql.cj.jdbc.Driver");
conn = DriverManager.getConnection(url,username,password);
//创建PreparedStatement
sql="select id, name, jiancheng, shenghui from province where id=?";
pst = conn.prepareStatement(sql);
//设置参数值
pst.setInt(1,proviceId);
//执行sql
rs = pst.executeQuery();
//遍历rs
/*while(rs.next()){ //当你的rs中有多余一条记录时。
name = rs.getString("name");
}*/
if( rs.next()){
province = new Province();
province.setId( rs.getInt("id"));
province.setName(rs.getString("name"));
province.setJiancheng(rs.getString("jiancheng"));
province.setShenghui(rs.getString("shenghui"));
}
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
} finally {
try{
if( rs != null){
rs.close();
}
if( pst != null){