岁月如歌,,,|

千夜ん

园龄:6年粉丝:0关注:0

Ajax

Ajax

AJAX = Asynchronous JavaScript and XML(异步的JavaScript和 XML)。

Ajax 不是一种新的编程语言,而是一种用于创建更好更快以及交互性更强的Web应用程序的技术。

C/S

增加B/S的体验性

B/S: 未来的主流,并且会爆发式的持续增长;

产品链:H5+网页+客户端+手机端(Android, IOS) +小程序

使用jQuery需要先导入jQuery的js文件;

1.原理图解

AJAX = Asynchronous JavaScript and XML(异步的JavaScript和 XML)。

AJAX可以在浏览器当中发送异步请求。请求A和请求B是异步的。谁也不需要等谁,类似于多线程并发。

AJAX的请求发送之后,不会出现页面清空,然后展示新页面的效果。AJAX不是这样的。

这个图想表示的最核心的是:AJAX请求1和AJAX请求2是异步的。并发的,谁也不干扰谁。

image-20220831221926772

浏览器上发送AJAX请求,这些代码是JS语法的代码。其实发送AJAX请求,就是需要编写JS代码的。

2.异步,同步

什么是异步,什么是同步?

  • 假设有t1和t2线程,t1和t2线程并发,就是异步。
  • 假设有t1和t2线程,t2在执行的时候,必须等待t1线程执行到某个位置之后t2才能执行,那么t2在等t1,显然他们是排队的,排队的就是同步。
  • AJAX是可以发送异步请求的。也就是说,在同一个浏览器页面当中,可以发送多个AJAX请求,这些AJAX请求之间不需要等待,是并发的。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script>
function sayHello() {
alert("Hello,world!");
}
</script>
<!--需求:页面上有一个按钮,用户点击按钮之后,执行一段JS代码-->
<input type="button" value="hello" onclick="sayHello()">
<!--通过JS代码给按钮绑定事件-->
<input type="button" value="hello2" id="helloBtn">
<script type="text/javascript">
//页面加载完毕之后,给id="helloBtn"的元素绑定鼠标单击事件
//这个function就是一个回调函数,这个回调函数什么时候执行?当load事件发生之后,
// 这个回调函数才会执行。
//什么是load事件?load事件什么时候发生? 注意:页面加载完毕之后,load事件发生。
window.onload = function (){
//获取id="helloBtn"的对象
var helloBtn = document.getElementById("helloBtn");
//给id="helloBtn"元素绑定click事件
//这个function也是一个回调函数,这个回调函数什么时候执行?
//当helloBtn被click的时候,被鼠标单击的时候,这个回调函数会执行。
//鼠标单击五次,这个回调函数就会被调用五次。
helloBtn.onclick = function (){
// alert("hello javaScript2");
//alert(this)
//这个回调函数中的this是谁呢?
//this是发生事件的事件源对象。是按钮发生了鼠标单击,那么this代表的就是这个按钮对象。
alert(this.value);
}
}
</script>
</body>
</html>

在AJAX的请求,以及AJAX接收服务器的响应,完全都是依靠XMLHttpRequest对象的。

XMLHttpRequest对象中的readyState属性记录下XMLHttpRequest对象的状态。

XMLHttpRequest对象的readyState属性对应的状态值:

0:请求未初始化

1:服务器连接已建立

2:请求已收到

3:正在处理请求

4:请求已完成且响应已就绪

当XMLHttpRequest对象的readyState属性的值变成4的时候,表示这个AJAX请求以及响应已经全部完成了。

image-20220831231151191

3.第一个Ajax程序

package com.feng;
import javax.servlet.annotation.WebServlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet("/ajaxrequest1")
public class AjaxRequest1Servlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//String s = null;
//s.toString();
// Servlet向浏览器响应一段数据
PrintWriter out = resp.getWriter();
//out对象向浏览器输出信息
//服务器的代码实际上和以前的代码还是完全一样的。
//只不过这个out在响应的时候,浏览器客户端的XMLHttpRequest对象会接收到这个响应的信息。
out.print("welcome to study ajax!!!");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script type="text/javascript">
window.onload = function () {
document.getElementById("helloBtn").onclick = function () {
//发送ajax get请求
// console.log("发送ajax get请求");
//1.第一步:创建AJAX核心对象XMLHttpRequest
var xhr = new XMLHttpRequest();
//2.第二步:注册回调函数
//这是一个回调函数,
// 这个函数在XMLHttpRequest对象的readyState状态值发生改变的时候被调用。
xhr.onreadystatechange = function (){
//这里的回调函数会被调用多次。
//0 -> 1 被调用一次
//1 -> 2 被调用一次
//2 -> 3 被调用一次
//3 -> 4 被调用一次
// console.log(xhr.readyState);
//当XMLHttpRequest对象的readyState的状态是4的时候,表示响应结束了。
// if(xhr.readyState == 4){
//
// }
if(this.readyState == 4){
//响应结束了
// console.log("响应结束了");
//响应结束之后,一般会有一个HTTP的状态码。
//HTTP状态码常见的包括:200表示成功了,404表示资源找不到,500表示服务器内部错误。
//HTTP状态码是HTTP协议的一部分,HTTP协议中规定的。服务器响应之后都会有一个状态码。
//获取HTTP状态码
// console.log("HTTP响应状态码:" +this.status);
if(this.status == 404){
alert("对不起,您访问的资源不存在,请检查请求路径");
}else if(this.status == 500){
alert("对不起,服务器发生了严重的内部错误,请联系管理员");
}else if(this.status == 200){
// alert("响应成功,完美");
// 200表示完全响应完毕,成功结束了。
// 通过XMLHttpRequest对象获取响应的信息。
// 通过XMLHttpRequest对象的responseText属性来获取响应的信息。
// alert(this.responseText)
//把响应信息放到div图层当中,渲染
document.getElementById("mydiv").innerHTML = this.responseText;
}
}
}
//3.第三步:开启通道(open只是浏览器和服务器建立连接,通道打开,并不会发送请求)
//XMLHttpRequest对象的open方法
//open(method,url,async,user,psw)
//method:请求的方式,可以是GET,也可以是POST,也可以是其它请求方式。
//url:请求的路径
//async:只能是true或者false,true表示此ajax请求是一个异步请求,
// false表示此ajax请求是一个同步请求,
//(大部分请求都是true,要求异步。极少数情况需要同步)
//user: 用户名 pwd:密码,用户名和密码是进行身份认证的,说明要想访问这个服务器上的资源,
// 可能需要提供一些口令才能访问。需不需要用户名和密码,主要看服务器的态度。
xhr.open("GET","/ajax1/ajaxrequest1",true);
//4.第四步:发送请求
xhr.send();
}
}
</script>
<!--给一个按钮,用户点击这个按钮的时候发送ajax请求-->
<input type="button" value="hello ajax" id="helloBtn">
<!--给一个div图层,ajax接收了响应的数据之后,在div中进行渲染-->
<div id="mydiv"></div>
</body>
</html>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
<version>9.0.58</version>
</dependency>
</dependencies>

4.AJAX GET请求

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>发送ajax get请求</title>
</head>
<body>
<script type="text/javascript">
window.onload = function (){
document.getElementById("btn").onclick = function (){
//1.创建AJAX核心对象
var xhr = new XMLHttpRequest();
//2.注册回调函数
xhr.onreadystatechange = function (){
if(this.readyState == 4){
debugger
if(this.status == 200){
//通过XMLHttpRequest对象的responseText属性可以获取到服务器响应回来的内容。
//并且不管服务器响应回来的是什么,
// 都以普通文本的形式获取。(服务器可能响应回来:普通文本, XML,JSON,HTML...)
// innerHTML属性是javascript中的语法,和ajax的XMLHttpRequest对象无关。
// innerHTML可以设置元素内部的HTML代码。(innerHTMl可以将后面的内容当做一段HTML代码解释并执行)
document.getElementById("myspan").innerHTML = this.responseText;
}else{
alert(this.status)
}
}
}
//3. 开启通道
xhr.open("GET","/ajax1/ajaxrequest2",true);
//4.发送请求
xhr.send();
}
}
</script>
<button id="btn">发送ajax get请求</button>
<span id="myspan"></span>
</body>
</html>
package com.feng;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
/**
* @auther fengpeng
* @date 2022/9/4
*/
@WebServlet("/ajaxrequest2")
public class AjaxRequest2Servlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置响应的内容类型以及字符集
resp.setContentType("text/html;charset=UTF-8");
//获取响应流
PrintWriter out = resp.getWriter();
//响应
out.print("<font color='red'>用户名已存在!!!</font>");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
  • AJAX get请求如何提交数据呢?
    • get请求提交数据是在"请求行"上提交,格式是: url?name=value&name=value&name=value...
    • 其实这个get请求提交数据的格式是HTTP协议中规定的,遵循协议即可。

提交数据

//3. 开启通道
// 获取到用户填写的usercode和username
var usercode = document.getElementById("usercode").value;
var username = document.getElementById("username").value;
xhr.open("GET","/ajax1/ajaxrequest2?usercode="+usercode+"&username="+username,true);
//4.发送请求
xhr.send();
}
}
</script>
usercode<input type="text" id="usercode"><br>
username<input type="text" id="username"><br>
<button id="btn">发送ajax get请求</button>
<span id="myspan"></span>
</body>

5.AJAX GET请求的缓存问题

  • 对于低版本的IE浏览器来说,AJAX的get请求可能会走缓存。存在缓存问题。

  • 对于现代的浏览器来说,大部分浏览器都不存在AJAX get缓存问题了。

  • 什么是AJAX GET请求缓存问题呢?

    • 在HTTP协议中是这样规定get请求的:get请求会被缓存起来。
    • 发送AJAX GET请求时,在同一个浏览器上,前后发送的AJAX请求路径一样的话,对于低版本的IE来说,第二次的AJAX GETq请求会走缓存,不走服务器。
  • POST请求在HTTP协议中规定的是:POST请求不会被浏览器缓存。

  • GET请求缓存的优缺点:

    • 优点:直接从浏览器缓存中获取资源,不需要从服务器上重新加载资源,速度较快,用户体验好。
    • 缺点:无法实时获取最新的服务器资源。
  • 浏览器什么时候会走缓存?

    • 第一:是一个GET请求
    • 第二:请求路径已经被浏览器缓存过了。第二次发送请求的时候,这个路径没有变化,会走浏览器缓存。
  • 如果是低版本的IE浏览器,怎么解决AJAX GET请求的缓存问题呢?

    • 可以在请求路径url后面添加一个时间戳,这个时间戳是随时变化的。所以每一次发送的请求路径都是不一样的,这样就不会走浏览器的缓存问题了。
    • 可以采用时间戳:"url?t=" + new Date().getTime()
    • 或者可以通过随机数:"url?t=" + Math.random()
    • 也可以随机数+时间戳...

6.AJAX POST请求

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>发送ajax post请求</title>
</head>
<body>
<script>
window.onload = function (){
document.getElementById("mybtn").onclick = function (){
// 发送AJAX POST请求
// 1.创建AJAX核心对象
var xhr = new XMLHttpRequest();
// 2.注册回调函数
xhr.onreadystatechange = function (){
if (this.readyState == 4) {
if(this.status == 200){
document.getElementById("mydiv").innerHTML = this.responseText
}else{
alert(this.status)
}
}
}
// 3.开启通道
xhr.open("POST","/ajax1/ajaxrequest3",true);
// 4.发送请求
xhr.send();
}
}
</script>
<button id="mybtn" >发送AJAX POST请求</button>
<div id="mydiv"></div>
</body>
</html>
package com.feng;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
/**
* @auther fengpeng
* @date 2022/9/5
*/
@WebServlet("/ajaxrequest3")
public class AjaxRequest3Servlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=UTF-8");
PrintWriter out = resp.getWriter();
out.print("<font color='red'>用户名已存在!!!</font>");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}

7.AJAX POST请求模拟表单提交数据

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>发送ajax post请求</title>
</head>
<body>
<script>
window.onload = function (){
document.getElementById("mybtn").onclick = function (){
// 发送AJAX POST请求
// 1.创建AJAX核心对象
var xhr = new XMLHttpRequest();
// 2.注册回调函数
xhr.onreadystatechange = function (){
if (this.readyState == 4) {
if(this.status == 200){
document.getElementById("mydiv").innerHTML = this.responseText
}else{
alert(this.status)
}
}
}
// 3.开启通道
xhr.open("POST","/ajax1/ajaxrequest3",true);
// 4.发送请求
// 怎么模拟AJAX提交form表单呢? 设置请求头的内容类型
// (这行代码非常关键,是模拟form表单提交的关键代码。)
// 设置请求头的内容类型时,必须在open之后。
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded")
// 放到send()这个函数的小括号当中的数据,会自动在请求体当中提交数据。
// 使用JS代码获取用户填写的用户名和密码
var username = document.getElementById("username").value;
var password = document.getElementById("password").value;
//xhr.send("注意格式: 放在这里的数据就是在请求体当中提交的,格式不能随便来,
// 还是需要遵循HTTP的协议:name=value&name=value&name=value)
xhr.send("username="+username+"&password="+password);
}
}
</script>
用户名<input type="text" id="username"><br>
密码<input type="password" id="password"><br>
<button id="mybtn" >发送AJAX POST请求</button>
<div id="mydiv"></div>
</body>
</html>
package com.feng;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
/**
* @auther fengpeng
* @date 2022/9/5
*/
@WebServlet("/ajaxrequest3")
public class AjaxRequest3Servlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=UTF-8");
PrintWriter out = resp.getWriter();
//out.print("<font color='red'>用户名已存在!!!</font>");
// 获取提交数据
String username = req.getParameter("username");
String password = req.getParameter("password");
out.print("用户名是:"+username+",密码是:"+password);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
  • AJAX POST请求和GET请求的代码区别在哪里?就是前端代码有区别。后端代码没有区别。
//4.发送AJAX POST请求
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded")
//获取表单中的数据
var username = document.getElementById("username").value;
var password = document.getElementById("password").value;
//send函数中的参数就是发送的数据,这个数据在"请求体"当中发送。
xhr.send("username"+ username+"&password"+ password)
  • 实现一个案例:使用AJAX POST请求实现用户注册的时候,用户名是否可用。(验证用户名是否可以注册),实现步骤如下:
    • 在前端,用户输入用户名之后,失去焦点事件blur发生,然后发送AJAX POST请求,提交用户名
    • 在后端,接收到用户名,连接数据库,根据用户名去表中搜索
    • 如果用户名已存在
      • 后端响应消息:对不起,用户名已存在(在前端页面以红色字体展示)
    • 如果用户名不存在
      • 后端响应消息:用户名可以使用(在前端页面以绿色字体展示)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>AJAX POST请求验证用户名是否可用</title>
</head>
<body>
<script type="text/javascript">
window.onload = function (){
document.getElementById("username").onfocus = function (){
document.getElementById("tipMsg").innerHTML = "";
}
document.getElementById("username").onblur = function (){
// console.log("正在发送AJAX POST请求验证用户名 ")
//发送AJAX POST请求
//1.
var xhr = new XMLHttpRequest();
//2.
xhr.onreadystatechange = function (){
if (this.readyState == 4) {
if(this.status == 200){
document.getElementById("tipMsg").innerHTML = this.responseText
}else {
alert(this.status)
}
}
}
//3.
xhr.open("POST","/ajax1/ajaxrequest4",true)
//4.
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded")
// 获取表单数据
var username = document.getElementById("username").value;
xhr.send("username="+ username)
}
}
</script>
用户名:<input type="text" id="username">
<span id="tipMsg"></span>
</body>
</html>
package com.feng;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.*;
/**
* @auther fengpeng
* @date 2022/9/12
*/
@WebServlet("/ajaxrequest4")
public class AjaxRequest4Servlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取用户名
String username = req.getParameter("username");
// 打布尔标记(一种编程模型)
boolean flag = false; // 默认是用户名不存在
//连接数据库验证用户名是否存在
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
// 1.注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");
// 2.获取连接
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC","root","fp");
// 3.获取预编译的数据库操作对象
String sql = "select * from mybatis.t_user where name = ?";
ps = conn.prepareStatement(sql);
ps.setString(1,username);
// 4.执行SQL语句
rs = ps.executeQuery();
// 5.处理结果集
if (rs.next()) {
// 用户名已存在。
flag = true;
}
} catch (Exception e) {
e.printStackTrace();
}finally {
// 6.释放资源
if (rs != null) {
try {
rs.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (ps != null) {
try {
ps.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
//响应结果到浏览器
resp.setContentType("text/html;charset=UTF-8");
PrintWriter out = resp.getWriter();
if (flag) {
//用户名已存在,不可用
out.print("<font color='red'>对不起,用户名已存在</font>");
}else {
// 用户名不存在,可以使用
out.print("<font color='green'>用户名可以使用</font>");
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}

8.创建json对象

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>json test</title>
</head>
<body>
<script type="text/javascript">
// 在javascript语言中怎么创建一个json对象呢? 语法是什么?
// var jsonobj = {
// "属性名1" : 属性值,
// "属性名2" : 属性值,
// "属性名3" : 属性值,
// "属性名4" : 属性值,
// "属性名5" : 属性值
// }
//
// 注意:
// 属性值的数据类型,那就随意了。可能是数字,可能是布尔类型,可能是字符串,可能是数组....
// 另一个json对象
var address = {
"city" : "北京",
"street" : "北京大兴区",
"zipcode" : "123456"
}
var user = {
"usercode" : 111,
"username" : "zhangsan",
"sex" : true,
"age" : 20,
"hobbies" : ["抽烟","喝酒","烫头"],
"addr" : address
}
// 访问json对象的属性
// 第一种方式
console.log(user.username)
console.log(user.usercode)
console.log(user.sex ? "男" : "女")
console.log(user.age)
for (var i = 0; i < user.hobbies.length ; i++) {
console.log(user.hobbies[i])
}
// 访问这个用户是哪个街道的?
console.log(user.addr.street)
//第二种方式
console.log(user["usercode"])
console.log(user["username"])
console.log(user["sex"] ? "男的" : "女的")
console.log(user["age"])
</script>
</body>
</html>

基于JSON的数据交换

  • 在WEB前端中,如何将一个json格式的字符串转换成json对象
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>json test2</title>
</head>
<body>
<script type="text/javascript">
// 这是一个json对象
var user = {
"username" : "zhangsan",
"password" : "123456"
}
// 是json对象,才能这样访问。
alert(user.username + "," +user.password)
// 从服务器端返回来的不是一个json对象,是一个json格式的字符串 , \转义字符
var fromJavaServerJsonStr = "{\"usercode\" : 111, \"age\" : 20}"
// 有两种方式:
// 第一种方式:使用eval函数。(javascript中的内容)
// 第二种方式:调用javascript语言中的内置对象JSON的一个方法parse
var jsonobj = JSON.parse(fromJavaServerJsonStr);
alert(jsonobj.usercode + "," +jsonobj.age)
</script>
</body>
</html>

9.连接数据库动态拼接JSON字符串

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>发送AJAX请求,显示学生列表</title>
</head>
<body>
<script type="text/javascript">
window.onload = function (){
document.getElementById("btn").onclick = function(){
// 1.创建核心对象
var xhr = new XMLHttpRequest();
// 2.注册回调函数
xhr.onreadystatechange = function (){
if (this.readyState == 4) {
if (this.status == 200) {
// document.getElementById("stutbody").innerHTML = this.responseText
// 将json格式的字符串转换成json对象
var stuList = JSON.parse(this.responseText);// 是一个数组,并且数组中有多个学生数据
var html = ""
for (var i = 0; i < stuList.length; i++) {
var stu = stuList[i]
html += "<tr>"
html += "<td>"+(i+1)+"</td>"
html += "<td>"+stu.name+"</td>"
html += "<td>"+stu.age+"</td>"
html += "<td>"+stu.addr+"</td>"
html += "</tr>"
}
document.getElementById("stutbody").innerHTML = html
}else{
alert(this.status)
}
}
}
// 3.开启通道
xhr.open("GET","/ajax1/ajaxrequest5",true)
// 4.发送请求
xhr.send()
}
}
</script>
<input type="button" value="显示学员列表" id="btn">
<table width="50%" border="1px">
<thead>
<tr>
<th>序号</th>
<th>姓名</th>
<th>年龄</th>
<th>住址</th>
</tr>
</thead>
<tbody id="stutbody">
<!--<tr>-->
<!-- <td>1</td>-->
<!-- <td>张三</td>-->
<!-- <td>20</td>-->
<!-- <td>北京大兴区</td>-->
<!--</tr>-->
<!--<tr>-->
<!-- <td>2</td>-->
<!-- <td>李四</td>-->
<!-- <td>22</td>-->
<!-- <td>北京海淀区</td>-->
<!--</tr>-->
</tbody>
</table>
</body>
</html>
package com.feng;
import javax.jws.WebService;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.*;
/**
* @auther fengpeng
* @date 2022/9/12
*/
@WebServlet("/ajaxrequest5")
public class AjaxRequest5Servlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//连接数据库,查询学员信息,拼接HTML代码,响应HTML代码到浏览器(这里就不再连接数据库了,写死了)
resp.setContentType("text/html;charset=UTF-8");
PrintWriter out = resp.getWriter();
//连接数据库,拼接HTML代码
StringBuilder html = new StringBuilder();
// 目前存在的缺点:在后端的java代码中又开始拼接HTML代码了。显然这是在后端java中写前端的HTML代码。不好维护。
// 能不能直接将数据返回,给WEB前端数据就行了。让WEB前端能够拿到数据就行,然后页面展示的功能交给WEB前端来处理。
// 我们后端的java代码能不能只返回数据???可以。(返回数据可以采用JSON的格式,也可以采用XML的格式)
// html.append("<tr>");
// html.append("<td>1</td>");
// html.append("<td>张三</td>");
// html.append("<td>20</td>");
// html.append("<td>北京大兴区</td>");
// html.append("</tr>");
// html.append("<tr>");
// html.append("<td>2</td>");
// html.append("<td>李四</td>");
// html.append("<td>22</td>");
// html.append("<td>北京海淀区</td>");
// html.append("</tr>");
//
//out.print(html);
// 将以上程序拼接HTML,换成拼接JSON格式的字符串
//String jsonStr = "[{\"name\":\"王五\",\"age\":20,\"addr\":\"北京大兴区\"},{\"name\":\"李四\",\"age\":22,\"addr\":\"北京海淀区\"}]";
// 准备StringBuilder对象,拼接JSON
StringBuilder json = new StringBuilder();
String jsonStr = "";
// 连接数据库,查询所有的学生,拼接json字符串
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
// 1.注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");
// 2.获取连接
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC","root","fp");
// 3.获取预编译的数据库操作对象
String sql = "select name,age,addr from mybatis.t_student";
ps = conn.prepareStatement(sql);
// 4.执行SQL语句
rs = ps.executeQuery();
json.append("[");
// 5.处理结果集
while(rs.next()) {
// 获取每个学生的信息
String name = rs.getString("name");
String age = rs.getString("age");
String addr = rs.getString("addr");
// 拼接json格式的字符串
// {"name":" 王五 ","age": 20 ,"addr":" 北京大兴区 "}
json.append("{\"name\":\"");
json.append(name);
json.append("\",\"age\":");
json.append(age);
json.append(" ,\"addr\":\"");
json.append(addr);
json.append("\"},");
}
jsonStr = json.substring(0,json.length()-1) + "]";
} catch (Exception e) {
e.printStackTrace();
}finally {
// 6.释放资源
if (rs != null) {
try {
rs.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (ps != null) {
try {
ps.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
//响应JSON格式的字符串给前端。/
out.print(jsonStr);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}

10.fastjson

package com.feng.fastjson;
import com.alibaba.fastjson.JSON;
import java.util.ArrayList;
import java.util.List;
public class FastjsonTest {
public static void main(String[] args) {
//创建一个User类型的对象
User user = new User("111", "zhangsan", 20);
//将以上的User对象转换为json格式的字符串
//使用阿里巴巴的fastjson组件中的JSON类即可。
//fastjson中又一个类,叫做:JSON。全部大写。
//JSON类中的方法都是静态的方法,直接调用即可。
String jsonstr = JSON.toJSONString(user);
System.out.println(jsonstr);
//尝试List集合是否可以转换成数组
List<User> userList = new ArrayList<>();
User user1 = new User("111", "lisi", 20);
User user2 = new User("111", "wangwu", 20);
userList.add(user1);
userList.add(user2);
String jsonStr2 = JSON.toJSONString(userList);
System.out.println(jsonStr2);
}
}

image-20221003214031730

11.基于XML的数据交换

  • 注意:如果服务器端响应XML的话,响应的内容类型需要写成:
resp.setContentType("text/xml;charset=utf-8");
  • xml和JSON都是常用的数据交换格式
    • XML体积大,解析麻烦,较少用。
    • JSON体积小,解析简单,较常用。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>使用XML完成数据交换</title>
</head>
<body>
<script type="text/javascript">
window.onload = function (){
document.getElementById("btn").onclick = function (){
//1.创建XMLHttpRequest对象
var xhr = new XMLHttpRequest();
//2.注册回调函数
xhr.onreadystatechange = function (){
if (this.readyState == 4) {
if (this.status == 200) {
//服务器端响应了一个XML字符串,这里怎么接收呢?
//使用XMLHttpRequest对象的responseXML属性,接收返回之后,可以自动封装成document对象(文档对象)
var xmlDoc = this.responseXML
// console.log(xmlDoc)
//获取所有的<student>元素,返回了多个对象,应该是数组。
var students = xmlDoc.getElementsByTagName("student")
// console.log(student[0].nodeName)
var html = ''
for (var i = 0; i < students.length; i++) {
var student = students[i]
//获取<student>元素下的所有子元素
html+="<tr>"
html+="<td>" +(i+1)+"</td>"
var nameOrAge = student.childNodes
for (var j = 0; j < nameOrAge; j++) {
var node = nameOrAge[j]
if (node.nodeName = "name") {
html += "<td>" +node.textContent+"</td>"
}
if (node.nodeName == "age") {
html += "<td>" +node.textContent+"</td>"
}
}
html += "</tr>"
}
document.getElementById("stutbody").innerHTML = html
}else {
alert(this.status)
}
}
}
//3.开启通道
xhr.open("GET","/f/ajaxrequest6",true);
//4.发送请求
xhr.send();
}
}
</script>
<button id="btn">显示学生列表</button>
<table width="500px" border="1px">
<thead>
<tr>
<th>序号</th>
<th>姓名</th>
<th>年龄</th>
</tr>
</thead>
<tbody id="stutbody">
<tr>
<td>1</td>
<td>zhangsan</td>
<td>20</td>
</tr>
<tr>
<td>2</td>
<td>lisi</td>
<td>22</td>
</tr>
</tbody>
</table>
</body>
</html>
package com.feng.fastjson;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
/**
* @Author feng peng
* @Date 2022/10/4
* @Time 9:13
*/
@WebServlet("/ajaxrequest6")
public class AjaxRequest6Servlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//注意:响应的内容类型是XML。
resp.setContentType("text/xml;charset=UTF-8");
PrintWriter out = resp.getWriter();
/*
* <students>
<student>
* <name>zhangsan</name>
* <age>20</age>
* </student>
* </student>
*<students>
<student>
* <name>lisi</name>
* <age>22</age>
* </student>
* </student>
*
* */
StringBuilder xml = new StringBuilder();
xml.append("<students>");
xml.append("student>");
xml.append("<name>zhangsan</name>");
xml.append("<age>20</age>");
xml.append("</student>");
xml.append("</students>");
xml.append("<students>");
xml.append("student>");
xml.append("<name>lisi</name>");
xml.append("<age>22</age>");
xml.append("</student>");
xml.append("</students>");
out.print(xml);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}

12.AJAX乱码问题

  • 测试内容:

    • 发送ajax get请求
      • 发送数据到服务器,服务器获取的数据是否乱码?
      • 服务器响应给前端的中文,会不会乱码?
    • 发送ajax post请求
      • 发送数据到服务器,服务器获取的数据是否乱码?
      • 服务器响应给前端的中文,会不会乱码?
  • 包括还要测试tomcat服务器的版本:

    • tomcat9 测试。

      • 响应中文的时候,会出现乱码,怎么解决?
      response.setContentType("text/html;charset=UTF-8");
      • 发送ajax post请求的时候,发送给服务器的数据,服务器接收之后乱码,怎么解决?
      request.setCharacterEncoding("UTF-8");

13.AJAX的异步和同步

  • 什么是异步?什么是同步?
    • ajax请求1和ajax请求2,同时并发,谁也不用等谁,这就是异步。(a不等b,b也不等a)
    • 如果ajax请求1在发送的时候需要等待ajax请求2结束之后才能发送,那么这就是同步。(a等待b,或者b等待a,只要发生等待,就是同步。)
  • 异步和同步在代码如何实现?
//假设这个是ajax请求1
//如果第三个参数是false:这个就表示"ajax请求1"不支持异步,也就是说ajax请求1发送之后,会影响其他的ajax请求的发送,只有当我这个请求结束之后,你们其他的ajax请求才能发送。
xhr1.open("请求方式","URL",false)
xhr1.send()
//假设这个是ajax请求2
//如果第三个参数是true:这个就表示"ajax请求2"支持异步请求,也就是说ajax请求2发送之后,不影响其他的ajax请求的发送。
xhr2.open("请求方式","URL",true)
xhr2.send()
  • 什么情况下用同步?(大部分情况下我们都是使用ajax异步方式,同步很少用。)
    • 举一个列子
      • 用户注册
        • 用户名需要发送ajax请求进行校验
        • 邮箱地址也需要发送ajax请求校验。
        • 其他的也可能需要发送ajax请求。。。
        • 并且最终注册按钮的时候,也是发送ajax请求进行注册。
        • 那么显然,注册的Ajax请求和校验的ajax请求不能异步,必须等待所有的校验ajax请求结束之后,注册的ajax请求才能发。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>演示ajax同步和异步</title>
</head>
<body>
<script type="text/javascript">
window.onload = function () {
document.getElementById("btn1").onclick = function () {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
document.getElementById("div1").innerHTML = this.responseText
}else {
alert(status)
}
}
}
// xhr.open("GET","/ajax/ajaxrequest8?"+ new Date().getTime(),true)
// 我不支持异步了,我这个请求只要发,你们都得靠边站。都得等着我结束你们才能发请求。
xhr.open("GET","/ajax/ajaxrequest8?"+ new Date().getTime(),false)
xhr.send()
}
document.getElementById("btn2").onclick = function () {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
document.getElementById("div2").innerHTML = this.responseText
}else{
alert(status)
}
}
}
xhr.open("GET","/ajax/ajaxrequest9?"+ new Date().getTime(),true)
xhr.send()
}
}
</script>
<button id="btn1">ajax请求1</button>
<div id="div1"></div>
<button id="btn2">ajax请求2</button>
<div id="div2"></div>
</body>
</html>
package com.feng;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @Author feng peng
* @Date 2022/10/4
* @Time 17:37
*/
@WebServlet("/ajaxrequest8")
public class AjaxRequest7Servlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
Thread.sleep(10*1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
response.setContentType("text/html;charset=UTF-8");
response.getWriter().print("ajax请求1");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
package com.feng;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @Author feng peng
* @Date 2022/10/4
* @Time 17:38
*/
@WebServlet("/ajaxrequest9")
public class AjaxRequest8Servlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
response.getWriter().print("ajax请求2");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}

13.AJAX代码封装

  • AJAX请求相关的代码都是类似的,有很多重复的代码,这些重复的代码能不能不写,能不能封装一个工具类。要发送ajax请求的话,就直接调用这个工具类中的相关函数即可。
  • 接下来,手动封装一个工具类,这个工具类我们可以把它看做是一个JS的库。我们把这个JS库起一个名字,叫做jQuery。(我这里封装的jQuery只是一个前端的库,和后端的java没有关系,只是为了方便web前端代码的编写,提高WEB前端的开发效率)

13.1 js中类的相关回顾

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>回顾javascript中类的定义,对象的创建。属性的访问,方法的访问。</title>
</head>
<body>
<script type="text/javascript">
// 在JS当中怎么定义一个类
function User(usercode,username){
//属性
this.usercode = usercode;
this.username = username;
// 方法(实例方法,通过对象调用的。)
this.doSome = function (){
console.log(username + " doSome....")
}
// 静态方法(直接用类名调用)
User.doOther = function (){
console.log("user doOther....")
}
}
//第二种定义类
/* User = function (usercode,username){
//属性
this.usercode = usercode;
this.username = username;
// 方法(实例方法,通过对象调用的。)
this.doSome = function (){
console.log(username + " doSome....")
}
// 静态方法(直接用类名调用)
User.doOther = function (){
console.log("user doOther....")
}
}*/
// 创建对象,访问对象的属性,访问对象的方法,访问静态方法
// User(); 直接这样调用,你只是把它当做一个普通的函数去执行,不会创建对象,在堆中没有这个对象。
// new User(); 这样调用的话,其实就是调用该类的构造方法,创建对象,并且在堆中分配空间。
var user = new User("111","zhangsan");
//访问属性
alert(user.usercode+ "," +user.username)
//调用方法(实例方法)
user.doSome()
// 调用静态方法
User.doOther()
// 后期如果想给某个类型扩展方法,还可以使用prototype属性
User.prototype.扩展的 = function (){
console.log("打印。。。")
}
user.扩展的()
</script>
</body>
</html>

13.2 自己封装jQuery

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>手动封装JS库jQuery</title>
</head>
<body>
<script type="text/javascript">
/*封装一个函数,通过这个函数可以获取到html页面中的节点,这个函数我给他起一个名字,叫做: jQuery*/
/*要封装的代码是:根据id来获取元素。document.getElementById("btn")*/
/*设计思路来自于CSS的语法。 #id 可以获取到这个元素*/
function jQuery(selector){ /*selector可能是#id,也可能是其他的选择器,例如类选择器: .class 也可以是任何类型(弱类型)*/
// 根据id获取元素
if (typeof selector == "string") {
if(selector.charAt(0) == "#"){
// selector是一个id选择器
/*var domObj = document.getElementById(selector.substring(1))*/
//升级成全局变量
domObj = document.getElementById(selector.substring(1))
//返回的dom对象
// return domObj
//返回的jQuery对象
return new jQuery()
}
}
//页面加载完毕之后,注册回调函数。
if (typeof selector == "function") {
window.onload = selector
}
// 定义一个html()函数,代替: domObj.innerHTML = ""
this.html = function (htmlStr){
domObj.innerHTML = htmlStr
}
// 定义一个click()函数,代替: domObj.onclick = function(){}
this.click = function (fun){
domObj.onclick = fun
}
this.val = function (v){
if (v == undefined) {
return domObj.value
}else{
domObj.value = v
}
}
}
$ = jQuery
/* window.onload = function (){
/!* document.getElementById("btn").onclick = function (){
document.getElementById("div1").innerHTML = "<font color='red'>用户名不可用!!!</font>"
}*!/
/!* jQuery("#btn").onclick = function (){
jQuery("#div1").innerHTML = "<font color='red'>用户名不可用!!!</font>"
}*!/
$("#btn").onclick = function (){
$("#div1").innerHTML = "<font color='red'>用户名不可用!!!</font>"
}
}*/
/* $(function (){} 作用是什么?*/
/* 只要你写上以上的代码,就表示在页面加载完毕之后,执行里面的回调函数。*/
/*$(function (){
$("#btn").onclick = function (){
$("#div1").innerHTML = "<font color='red'>用户名不可用!!!</font>"
}
})*/ /*$--> jQuery (function)--> 传递了一个函数 */
$(function (){
$("#btn").click(function (){
$("#div1").html("<font color='red'>用户名不可用!!!</font>")
// 获取到文本框中的用户名
/* var username = document.getElementById("username").value
alert(username)*/
var username = $("#username").val();
alert(username)
// 修改文本框的value
// document.getElementById("username").value = "呵呵"
$("#username").val("呵呵。。。。")
})
})
</script>
用户名:<input type="text" id="username">
<button id="btn">显示信息</button>
<div id="div1"></div>
</body>
</html>

把封装的jQuery放入js文件中

function jQuery(selector){
if (typeof selector == "string") {
if(selector.charAt(0) == "#"){
domObj = document.getElementById(selector.substring(1))
return new jQuery()
}
}
if (typeof selector == "function") {
window.onload = selector
}
this.html = function (htmlStr){
domObj.innerHTML = htmlStr
}
this.click = function (fun){
domObj.onclick = fun
}
this.val = function (v){
if (v == undefined) {
return domObj.value
}else{
domObj.value = v
}
}
}
$ = jQuery

测试封装的jQuery

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>测试我们自己编写的jQuery库(jQuery本质上就是JS的库)</title>
</head>
<body>
<!--使用jQuery库的第一件事,是把jQuery库引进来-->
<script type="text/javascript" src="js/jQuery-1.0.0.js"></script>
<script type="text/javascript">
$(function (){
$("#btn").click(function (){
// alert("hello")
// 获取文本框内容
alert($("#usercode").val())
//修改文本框的value
$("#usercode").val("张三")
//设置div内容
$("#mydiv").html("我们自己封装的div!!!")
})
})
</script>
<button id="btn">hello</button>
<br>
用户代码:<input type="text" id="usercode">
<br>
<div id="mydiv"></div>
</body>
</html>

13.3 手动开发jQuery,源代码

jQuery.js

function jQuery(selector){
if (typeof selector == "string") {
if(selector.charAt(0) == "#"){
domObj = document.getElementById(selector.substring(1))
return new jQuery()
}
}
if (typeof selector == "function") {
window.onload = selector
}
this.html = function (htmlStr){
domObj.innerHTML = htmlStr
}
this.click = function (fun){
domObj.onclick = fun
}
this.val = function (v){
if (v == undefined) {
return domObj.value
}else{
domObj.value = v
}
}
//静态的方法,发送ajax请求
/**
* 分析:使用ajax函数发送的ajax请求的时候,需要程序员给我们传过来什么?
* 请求的方式(type): GET/POST
* 请求的URL(url): url
* 请求时提交的数据(data): data
* 请求时发送异步请求还是同步请求(async): true表示异步,false表示同步。
*
*/
jQuery.ajax = function (jsonArgs){
//1.
var xhr = new XMLHttpRequest();
//2.
xhr.onreadystatechange = function (){
if (xhr.readyState == 4) {
if (xhr.status == 200) {
// 我们这个工具类在封装的时候,先不考虑那么多,假设服务器返回的都是json格式的字符串。
var jsonObj = JSON.parse(this.responseText)
// 调用函数
jsonArgs.success(jsonObj)
}
}
}
if(jsonArgs.type.toUpperCase() == "POST"){
//3.
xhr.open("POST",jsonArgs.url,jsonArgs.async)
//4.
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded")
xhr.send(jsonArgs.data)
}
if (jsonArgs.type.toUpperCase() == "GET") {
xhr.open("GET",jsonArgs.url + "?" +jsonArgs.data,jsonArgs.async)
xhr.send()
}
}
}
$ = jQuery
new jQuery()
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>测试我们自己手动开发的jQuery库</title>
</head>
<body>
<!--引入自己写的jQuery库-->
<script type="text/javascript" src="js/jQuery-1.0.0.js"></script>
<script type="text/javascript">
$(function (){
$("#btn1").click(function (){
//发送ajax请求
$.ajax({
// type : "GET",
type : "POST",
url : "/ajax/ajaxrequest11",
data : "username=" + $("#username").val(),
async : true,
success : function (json){
$("#div1").html(json.uname)
}
})
})
})
</script>
<button id="btn1">发送ajax请求</button>
<br>
用户名: <input type="text" id="username">
<br>
<div id="div1"></div>
</body>
</html>
package com.feng;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Locale;
/**
* @Author feng peng
* @Date 2022/10/5
* @Time 17:47
*/
@WebServlet("/ajaxrequest11")
public class AjaxRequest10Servlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("username");
response.setContentType("text/html;charset=UTF-8");
//{"username","zhangsan"}
response.getWriter().print("{\"uname\":\""+username.toUpperCase()+"\"}");
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("username");
response.setContentType("text/html;charset=UTF-8");
//{"username","zhangsan"}
response.getWriter().print("{\"uname\":\""+username.toLowerCase()+"\"}");
}
}
  • 使用以上库,怎么用?
<!--引入自己写的jQuery库-->
<script type="text/javascript" src="js/jQuery-1.0.0.js"></script>
<script type="text/javascript">
$(function (){
$("#btn1").click(function (){
//发送ajax请求
$.ajax({
// type : "GET",
type : "POST",
url : "/ajax/ajaxrequest11",
data : "username=" + $("#username").val(),
async : true,
success : function (json){
$("#div1").html(json.uname)
}
})
})
})
</script>

14.AJAX实现省市联动

  • 什么是省市联动?

    • 在网页上,选择对应的省份之后,动态的关联出该省份对应的市。选择对应的市之后,动态的关联出该市对应的区。(首先要清楚需求)
  • 进行数据库表的设计

    • t_area (区域表)
      id(PK-自增) code name pcode
      -------------------------------------------------------
      1 001 河北省 null
      2 002 河南省 null
      3 003 石家庄 001
      4 004 邯郸 001
      5 005 郑州 002
      6 006 洛阳 002
      7 007 丛台区 004

      将全国所有的省,市,区,县等信息都存储到一张表当中。

      采用的存储方式实际上是code pcode形式。

自定义的jQuery库:

function jQuery(selector){
if (typeof selector == "string") {
if(selector.charAt(0) == "#"){
domObj = document.getElementById(selector.substring(1))
return new jQuery()
}
}
if (typeof selector == "function") {
window.onload = selector
}
this.html = function (htmlStr){
domObj.innerHTML = htmlStr
}
this.click = function (fun){
domObj.onclick = fun
}
this.change = function (fun){
domObj.onchange = fun
}
this.val = function (v){
if (v == undefined) {
return domObj.value
}else{
domObj.value = v
}
}
//静态的方法,发送ajax请求
/**
* 分析:使用ajax函数发送的ajax请求的时候,需要程序员给我们传过来什么?
* 请求的方式(type): GET/POST
* 请求的URL(url): url
* 请求时提交的数据(data): data
* 请求时发送异步请求还是同步请求(async): true表示异步,false表示同步。
*
*/
jQuery.ajax = function (jsonArgs){
//1.
var xhr = new XMLHttpRequest();
//2.
xhr.onreadystatechange = function (){
if (xhr.readyState == 4) {
if (xhr.status == 200) {
// 我们这个工具类在封装的时候,先不考虑那么多,假设服务器返回的都是json格式的字符串。
var jsonObj = JSON.parse(this.responseText)
// 调用函数
jsonArgs.success(jsonObj)
}
}
}
if(jsonArgs.type.toUpperCase() == "POST"){
//3.
xhr.open("POST",jsonArgs.url,jsonArgs.async)
//4.
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded")
xhr.send(jsonArgs.data)
}
if (jsonArgs.type.toUpperCase() == "GET") {
xhr.open("GET",jsonArgs.url + "?" +jsonArgs.data,jsonArgs.async)
xhr.send()
}
}
}
$ = jQuery
new jQuery()

定义类,用于json格式传参:

package com.feng.beans;
/**
* @Author feng peng
* @Date 2022/10/5
* @Time 22:25
*/
public class Area {
private String code;
private String name;
public Area() {
}
public Area(String code, String name) {
this.code = code;
this.name = name;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>省市联动</title>
</head>
<body>
<!--引入我们自己编写的jQuery库-->
<script type="text/javascript" src="js/jQuery-1.0.0.js"></script>
<script type="text/javascript">
$(function (){
//发送ajax请求,获取所有的省份。省份的pcode是null
$.ajax({
type: "get",
url: "/ajax/listArea",
data: "t="+ new Date().getTime(),
async: true,
success: function (jsonArr){ /*在jQuery库中,把返回的json字符串解析成json对象返回。*/
// [{"code":"001","name":"河北省"},{"code":"002","name":"河南省"}]
// 以上格式的json是我们自己设计出来的,希望服务器能够给我们返回这样一个json格式的字符串。
var html = "<option value=''>--请选择省份--</option>";
for (var i = 0; i < jsonArr.length; i++) {
var area = jsonArr[i]
html += "<option value='"+area.code+"'>" +area.name+ "</option>"
}
$("#province").html(html)
}
})
// 只要change发生,就发送ajax请求
/*jQuery库中记得写change事件*/
$("#province").change(function (){
// alert("发送ajax请求")
// alert(this)
// alert(this.value)
//发送ajax请求
$.ajax({
type: "get",
url: "/ajax/listArea",
data: "t="+ new Date().getTime()+"&pcode=" + this.value,
async: true,
success: function (jsonArr){
// [{"code":"006","name":"xxx"},{"code":"008","name":"yyyy"}]
var html = "<option value=''>--请选择市--</option>";
for (var i = 0; i < jsonArr.length; i++) {
var area = jsonArr[i]
html += "<option value='"+area.code+"'>" +area.name+ "</option>"
}
$("#city").html(html)
}
})
})
})
</script>
<select id="province">
<!-- <option value="">请选择省份</option>
<option value="001">河北省</option>
<option value="002">河南省</option>-->
</select>
<select id="city">
</select>
</body>
</html>
package com.feng.servlet;
import com.alibaba.fastjson2.JSON;
import com.feng.beans.Area;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
/**
* @Author feng peng
* @Date 2022/10/5
* @Time 22:09
*/
@WebServlet("/listArea")
public class ListAreaServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String pcode = request.getParameter("pcode");
// 连接数据库,获取所有的对应区域。最终响应一个JSON格式的字符串给WEB前端。
Connection conn = null;
PreparedStatement ps =null;
ResultSet rs = null;
List<Area> areaList = new ArrayList<>();
try {
// 注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");
// 获取连接
String url = "jdbc:mysql://localhost:3306/mybatis?userUnicode=true&characterEncoding=UTF-8";
String user = "root";
String password = "fp";
conn = DriverManager.getConnection(url,user,password);
// 获取预编译数据库操作对象
String sql = "";
if (pcode == null) {
sql = "select code,name from t_area where pcode is null";
ps = conn.prepareStatement(sql);
}else{
sql = "select code,name from t_area where pcode = ?";
ps = conn.prepareStatement(sql);
ps.setString(1,pcode);
}
// 执行SQL
rs = ps.executeQuery();
// 处理结果集
while (rs.next()) {
String code = rs.getString("code");
String name = rs.getString("name");
Area a = new Area(code,name);
areaList.add(a);
}
} catch (Exception e) {
e.printStackTrace();
}finally {
// 释放资源
if (rs != null) {
try {
rs.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (ps != null) {
try {
ps.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
response.setContentType("text/html;charset=UTF-8");
// 使用fastjson将java对象转换成json字符串。
String json = JSON.toJSONString(areaList);
// 响应JSON。
response.getWriter().print(json);
}
}

15.AJAX 跨域

15.1 理解

image-20221006091206071

超链接可以跨域吗?

配置两个Tomcat

image-20230606211809508

image-20230606211826627

image-20230606212014622

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>a应用的index页面</title>
</head>
<body>
<!--通过超链接的方式可以跨域吗?-->
<a href="http://localhost:8082/b/index.html">b的index页面(跨域访问)</a>
</body>
</html>

image-20230606212111446

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>b应用的index页面</title>
</head>
<body>
<h1>b应用的index页面</h1>
</body>
</html>

运行测试

image-20230606212246466

form表单发送请求可以跨域吗?

image-20230606214710201

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>a应用的index页面</title>
</head>
<body>
<!--通过超链接的方式可以跨域吗?-->
<a href="http://localhost:8082/b/index.html">b的index页面(跨域访问)</a>
<!--form表单发送请求可以跨域吗?-->
<form action="http://localhost:8082/b/user/reg" method="post">
用户名:<input type="text" name="username"><br>
密码:<input type="password" name="password"><br>
<input type="submit" value="注册">
</form>
</body>
</html>

image-20230606214816978

UserRegServlet

package com.feng.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/user/reg")
public class UserRegServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 获取用户名和密码
String username = req.getParameter("username");
String password = req.getParameter("password");
//响应到前端
resp.getWriter().print(username+" : " + password);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}

运行测试

image-20230606215004505

image-20230606215120322

本文作者:千夜ん

本文链接:https://www.cnblogs.com/fengpeng123/p/17951215

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   千夜ん  阅读(13)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起