目录
1 传统请求的缺点
2 Ajax概述
3 readyState状态值得理解
4 第一个Ajax请求详解
4.1 发送Ajax请求步骤
4.2 使用ajax发送get请求提交数据给服务器
4.3 POST请求模拟表单提交数据
5 验证用户名是否可用
6 基于JSON的数据交换
6.1 什么是JSON
6.2 在前端中如何将JSON字符串转为JSON对象
6.3 前后端进行JSON格式的字符串进行数据的交换
6.4 连接数据库得到JSON格式字符串数据
7 基于XML数据格式交换数据
8 关于乱码问题
9 Ajax的异步与同步
为什么要学习Ajax?
传统请求方式有缺点:在之前我们学习发送请求的时候,每发送一次请求,页面就会刷新一次,也就是说当我在一个页面发送请求的时候,请求到另一个页面,整个页面就会变为请求后的页面。假如我正在看视频,视频正在缓存,但是这时我想登录,传统请求这时就会跳转到登录界面,我看的视频界面就没了,缓存也没了,需要重新打开视频,体验极差。
大概演示一下传统请求的请求是什么样子,下面是几个我们学过的请求:
这时的页面底层是这个样子:
我们点击一个请求:
我们发现页面直接刷新为请求后的页面了,大概这个意思。我们使用Ajax就可以使这两个页面变成一个页面,之前的请求就不用了。经典白学。
Ajax应用程序执行的过程是怎样的
那么学习Ajax之前要学习哪些内容呢,首先是JavaScript,我还不是很熟悉,再见,先滚去学JavaScript了。
XMLHttpRequest对象的readyState属性对应的状态值:
当XMLHttpRequest对象的readyState属性的值变成4的时候,表示这个Ajax请求响应已经全部完成
发送Ajax请求主要分为四步:
第一步:创建Ajax核心对象XMLHttpRequest,直接new就好
第二步:注册回调函数
第三步:开启通道(open只是浏览器和服务器建立连接,通道打开,并不会发送请求)
第四步:发送请求,使用对象XMLHttpRequest的send方法
代码如下:
Title
@WebServlet("/ajaxrequest")
public class AjaxServlet01 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
PrintWriter out = response.getWriter();
out.write("hello ajax");
}
}
可以直接在请求路径后面加上?然后拼接请求内容如下:
var username = document.getElementById("username").value
var password = document.getElementById("password").value
xhr.open("GET","/ajax/ajaxrequest2?username="+username+"&password="+password,true)
在重写ajax请求的代码时,出现一个错误,把onclick写成了click,焯!!
ajax get请求在低版本的ie浏览器上会出现缓存问题,就是访问同一个资源也就是url是同一个就会直接去找缓存而不是找服务器,这样当然速度会快,但是服务器更新了它依然找缓存,这就不好了,但是目前主流浏览器不存在这种问题了。。需要注意的是:post请求不会有缓存问题。
怎么使用AJax提交POST请求呢,肯定不能放在url后面进行请求,那是get请求了。可以放在send方法里面,要注意格式(name=value&name=value),其实就和get请求一样,不过是放在send函数中而已。但是这样还不够,我们还要send之前open之后执行setRequestHeader方法,它用来设置请求头的内容类型,用来模拟Ajax提交form表单,具体如下:
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded")
var username = document.getElementById("username").value
var password = document.getElementById("password").value
xhr.send("username="+username+"&password="+password)
实现一个小案例:使用Ajax post请求实现用户注册的时候,用户名是否可用,实现步骤如下:
代码如下:
前端代码朴实无华,和上面差不多,主要展示后端代码:
package com.itzw.ajax.servlet;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.*;
@WebServlet("/ajaxrequest4")
public class AjaxServlet04 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
String username = request.getParameter("username");
//out.print("username:"+username);
//连接数据库
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
//打布尔标记
boolean ok = false;
try {
//注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//获取连接
String url = "jdbc:mysql://127.0.0.1:3306/db1";
String user = "root";
String password = "123456";
conn = DriverManager.getConnection(url, user, password);
//获取预编译的数据库操作对象
String sql = "select username from t_user where username = ?";
ps = conn.prepareStatement(sql);
ps.setString(1,username);
//执行SQL语句
rs = ps.executeQuery();
//处理结果集
if (rs.next()){
//有结果说明用户名重复
ok = true;
}
} catch (Exception e) {
e.printStackTrace();
}finally {
//释放资源
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (ps != null) {
try {
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
//判断前端该输出什么内容
if (ok){
//用户名重复
out.print("用户名重复,请重新输入");
}else {
//用户名可以使用
out.print("用户名可以使用");
}
}
}
我们发现目前存在的缺点:当我们想将数据传到前端,需要在后端进行java代码和HTML代码的拼接,这显然是非常愚蠢的,我们能不能直接将数据返回,让web前端能够拿到数据就行。当然可以,返回数据可以采用JSON的格式,也可以是XML格式,重点在JSON。
这个在JavaScript中学过,这里简单回顾一下
有两种方式
第一种:使用eval函数
第二种:调用JavaScript语言中的内置对象JSON的一个方法parse即可。
第一种JavaScript中讲到过,第二种比较简单,下面演示一下第二种:
//这是从java中获取到的JSON格式的字符串数据
var fromJavaData = "{\"username\":\"张麻子\",\"password\":\"123456\"}";
//这样就可以将字符串转为JSON对象
var jsonObj = JSON.parse(fromJavaData)
Title
序号
学号
姓名
住址
后端模拟从数据库得到数据
PrintWriter out = response.getWriter();
//模拟从数据库获取到的数据
String stuList = "[{\"sno\":\"110\",\"name\":\"王德发\",\"addr\":\"南京市\"},{\"sno\":\"120\",\"name\":\"张麻子\",\"addr\":\"北京市\"}]";
out.print(stuList);
我们可以连接数据库得到数据然后一点点将得到的数据拼成JSON格式的字符串,显然这个很麻烦,还好有个工具可以使用,这个工具为:fastjson-1.2.2,它是一个jar包,下面演示:
List stuList = new ArrayList<>();
while (rs.next()){
String sno = rs.getString("sno");
String name = rs.getString("name");
String addr = rs.getString("addr");
Student s = new Student(sno,name,addr);
stuList.add(s);
}
//将list集合转为JSON字符串
jsonStr = JSON.toJSONString(stuList);
这个jar包有个JSON类,用它调用toJSONString方法即可,需要注意的是,若想使用这个方法,需要先创建一个类,然后将数据封装到这个类里面然后再把它放在toJSONString里转换。演示:
使用xml格式交换数据使用较少,这里演示一下即可
Title
序号
姓名
年龄
后端提交的数据:
//response.setContentType("text/xml");
PrintWriter out = response.getWriter();
StringBuilder stuXML = new StringBuilder();
stuXML.append("");
stuXML.append(" ");
stuXML.append(" 马邦德 ");
stuXML.append(" 43 ");
stuXML.append(" ");
stuXML.append(" ");
stuXML.append(" 张麻子 ");
stuXML.append(" 44 ");
stuXML.append(" ");
stuXML.append(" ");
out.print(stuXML);
对于tomcat10来说不需要考虑乱码问题,都给我用10,nnd
对于tomcat9来说:
大部分情况下都是使用异步,但有时我们需要使用同步,比如在我们注册时:需要输入很多信息,在这些信息验证(验证用户名是否符合要求之类的)前不能进行注册,所以这时使用异步就会出现问题,同步等待前面信息验证完才能进行注册
到目前为止Ajax的基本语法就结束了