1、Ajax简介
(1)简介
Ajax即“Asynchronous JavaScript And XML”(异步 javaScript 和 XML),是指一种创建交互式网页应用的网页开发技术。
Ajax是指一种用于创建快速动态网页的技术。
Ajax是指一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。
通过在后台与服务器进行少量数据交换,Ajax可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。
(2)应用场景
在线视频、直播平台等...评论实时更新、点赞、小礼物等...
会员注册是的信息验证,手机号、账号唯一
百度关键词搜索补全功能
(3)同步方式与异步方式区别
同步方式发送请求:
发送一个请求,需要等待响应返回,然后才能发送下一个请求,如果该请求没有响应,不能发送下一个请求,客户端会处于一直等待过程中。
异步方式发送请求:
发送一个请求,不需要等待响应返回,随时可以再发送下一个请求,即不需要等待。
2、JS原生方式实现异步
(1)实现步骤
1、定义一个XMLHttpRequest核心对象xhr;
2、通过xhr.open方法给当前对象提供访问方式、URL等。
3、发送当前的请求至指定的URL。
4、接收返回值并处理。
(2)案例需求
需求:前台页面通过一个按钮向后发送一个Ajax请求,后台做完处理后向前台页面响应一段文本信息显示在页面上。
(3)案例实现
jsp代码:
<%--
Created by IntelliJ IDEA.
User: why
Date: 2022/4/18
Time: 9:40
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%-- 实现点赞--%>
点赞的次数: <span id="s1">0</span> <br>
<button onclick="fun1()">点赞</button>
</body>
</html>
<script>
//原生ajax写起来比较复杂,以后不使用
//点击事件
function fun1() {
//获取span标签元素
var s1 = document.getElementById("s1");
//获取s1的文本值
var number = s1.innerText;
//请求后台 把number传递过去
//使用原生的ajax请求
//1、创建核心对象
var xhr = new XMLHttpRequest();
//2、组装地址 open(method,url)
xhr.open("get","demo01Servlet?number=" + number);
//3、发送请求
xhr.send();
//4、去拿数据
/**
* 存有 XMLHttpRequest 的状态。从 0 到 4 发生变化。
readyState
0: 请求未初始化
1: 服务器连接已建立
2: 请求已接收
3: 请求处理中
4: 请求已完成,且响应已就绪
*/
//状态码一改变就会触发onreadystatechange事件
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
//请求和响应是成功的 需要去拿到响应的数据
var text = xhr.responseText;
//修改span的文本值
s1.innerText = text;
}
}
}
</script>
Servlet代码:
package com.ujiuye.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;
import java.io.PrintWriter;
@WebServlet("/demo01Servlet")
public class Demo01Servlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
//设置请求响应字符集
req.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
//接收number
String number = req.getParameter("number");
int n = Integer.parseInt(number) + 1;
//把n 写回去 响应体去写
PrintWriter w = resp.getWriter();
w.print(n);
}
}
3、jQuery方式实现异步
jQuery是一个优秀的js框架,自然对JS原生的AJAX进行了封装,封装后的Ajax的操作方法更简洁,功能更强大。
与Ajax操作相关的jQuery方法经常使用的有三种:
请求方式 | 语法 |
Ajax请求 | $.ajax([settings]) |
GET请求 | $.get(url,[data],[callback],[type]) |
POST请求 | $.post(url,[data],[callback],[type]) |
(1)Ajax请求
语法格式:
$.ajax({
//请求的地址
url:"",
//携带参数 data:{key:value,key1:value1,key2:value2}
data:{},
//请求的类型 get/post
type: "get/post"
//是同步还是异步请求 true 代表异步 默认 false 同步 一般不写的
async:true /false,
//返回的数据类型 text / json
dataType:"text",
//成功的回调函数 data表示返回的数据
success:function(data) {
},
//失败的回调函数 一般不写
error:function() {
}
})
属性解析:
参数名称 | 描述 |
url | 请求的服务器端url地址,与form表单中的action一样,都是代表请求的路径 |
data | 前台需要向后台传递的数据(键值对形式) |
type | 和form表单中method对应,代表请求类型get/post |
async | 取值是布尔类型true/false,分别表示异步和同步,默认true(异步),一般不建议写 |
dataType | 回传的数据类型。text、xml、html、json.... |
success | 成功的回调函数,参数obj表示返回值 |
error | 失败的回调函数,一般不写 |
注意事项:
1.每个属性后都要跟随一个英文逗号,最后一个不用。
2.每一个属性都是键值对的形式存在,中间用英文冒号:隔开。
3.data:{}是一个特殊的写法,值是一个{},里面使用键值对存储。
4.以上属性没有先后顺序要求。
案例:
<%--
Created by IntelliJ IDEA.
User: why
Date: 2022/4/18
Time: 10:26
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<%-- 引入jQuery.js--%>
<script src="js/jquery-3.6.0.min.js"></script>
<style>
div {
/*绝对定位*/
position: absolute;
left: 200px;
bottom: 200px;
}
</style>
</head>
<body>
<%--
1、前提 导入jQuery的js文件
2、$.ajax语法
$.ajax({
//请求的地址 相当于form表单的action
url:"",
//传递的参数 key和value通过冒号进行分割,多个参数通过逗号进行分割
data:{key1:value1,key2:value2.....},
//请求的方式
type:"get/post",
//同步请求还是异步 true 异步 false同步 不写默认就是异步
async:true/false,
//返回的数据类型 text 文本
dataType:"text",
//成功的回调函数 obj代表返回值
success:function(obj) {
},
//失败的回调函数
error:function() {
}
})
3、注意事项
单词严格区分大小写,不能写错
每个参数的结束使用逗号进行分割,最后一个参数不需要加逗号
错误的回调函数和async一般不写
--%>
<marquee>滚动标签</marquee>
<div>
弹幕: <input id="inp" type="text" name="msg" value="">
<button id="btn">发送弹幕</button>
</div>
</body>
</html>
<script>
/**
* 1、报错了或者没有出来结果
* 点开浏览器打开console控制台,看控制台报错没有
* 控制台没有报错,加打印语句
* 点击事件是否执行
* 是否到达后台
* 是否返回数据
*
*/
//给发送弹幕一个点击事件
$("#btn").click(function () {
//获取用户输入的弹幕
var msg = $("#inp").val();
//请求后台 携带参数msg
$.ajax({
//请求的地址
url:"demo02Servlet",
//携带的参数
data:{"msg":msg},
//请求的方式
type:"get",
//返回的数据类型
dataType:"text",
//成功的回调函数
success:function (obj) {
//obj代表返回的数据
$("marquee:last").after(obj);
}
})
})
</script>
package com.ujiuye.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;
import java.io.PrintWriter;
@WebServlet("/demo02Servlet")
public class Demo02Servlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
//设置请求响应字符集
req.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
//接收msg
String msg = req.getParameter("msg");
msg = "<marquee>" + msg + "</marquee>";
//响应数据
PrintWriter w = resp.getWriter();
w.print(msg);
}
}
(2)GET请求
语法格式:
$.get(url, [data], [callback], [type]);
$.get("demo03Servlet",{key,value},function(data) {
},"text/json")
$.get("demo03Servlet",function(data) {
})
属性解析:
参数名称 | 描述 |
url | 请求的服务器端url地址,与form表单中的action一样,都是代表请求的路径 |
data | 前台需要向后台穿的数据(键值对形式) 非必须的 |
callback | 当请求成功后的回调函数,可以在函数体中编写我们的逻辑代码 非必须 |
type | 预期的返回数据的类型,取值可以是text、xml、html、json... 非必须 |
注意事项:这种写法功能和$.ajax是一样的,但是严格要求属性顺序。
(3)POST请求
语法格式:
$.post(url,[data],[callback],[type]);
属性解析:
参数名称 | 描述 |
url | 请求的服务器url地址,与form表单中的action一样,都是代表请求的路径 |
data | 前台需要向后台传递的数据(键值对形式) 非必须的 |
callback | 当请求成功后的回调函数,可以在函数体中编写我们的逻辑代码 非必须的 |
type | 预期的返回数据类型,取值可以是text、xml、html、json... 非必须的 |
(4)$.ajax与$.get | $.post异同
相同点:都是jQuery封装的方法实现异步交互。
不同点:$.ajax()是jQuery的第一次封装,使用时稍显麻烦,但是功能强大,覆盖了get和poat请求,有错误调试能力,写法顺序可以改变。
$.post()和$.get()是jQuery Ajax的第二次封装,由于$.Ajax()写法过于臃肿。
(5)案例:校验用户名是否唯一
案例需求:
在用户注册页面,输入用户名,当用户名输入框失去焦点时,发送异步请求,将输入框的用户名传递给服务器进行是否存在的校验。
jsp代码:
<%--
Created by IntelliJ IDEA.
User: why
Date: 2022/4/18
Time: 11:28
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<script src="js/jquery-3.6.0.min.js"></script>
</head>
<body>
<%--
注册功能验证账号是否唯一
--%>
账号: <input id="username" type="text" name="username" value="">
<span id="s1"></span><br>
</body>
</html>
<script>
/*
$.get(url,data,success,dataType)
$.get和$.post是对$.ajax进行二次封装,参数的顺序不能改变
$.get("demo03Servlet",{"username":"zhangsan"},function(obj) {
},"text")
$.get("demo03Servlet",function(obj) {
})
*/
//失去焦点事件
$("#username").blur(function () {
//获取用户输入的账号
var username = $(this).val();
//可以将参数拼接到url地址后面
$.get("demo03Servlet?username=" + username,function (obj) {
//obj 代表true和false 是字符串类型
if (obj == "true") {
//账号可用
$("#s1").text("账号可用");
$("#s1").css("color","green");
}else {
//账号不可用
$("#s1").text("账号不可用");
$("#s1").css("color","red");
}
})
})
</script>
servlet代码:
package com.ujiuye.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;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
@WebServlet("/demo03Servlet")
public class Demo03Servlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
//设置请求响应字符集
req.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
String username = req.getParameter("username");
List<String> lists = new ArrayList<>();
lists.add("张三");
lists.add("李四");
lists.add("王五");
lists.add("赵六");
lists.add("田七");
PrintWriter w = resp.getWriter();
//判断
// if (lists.contains(username)) {
// //账号已存在
// w.print(false);
// }else {
// //账号可用
// w.print(true);
// }
w.print(!lists.contains(username));
}
}