四 Ajax
4.1 什么是ajax
- AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)。
- AJAX 不是新的编程语言,而是一种使用现有标准的新方法。
- AJAX 最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。
- AJAX 不需要任何浏览器插件,但需要用户允许 JavaScript 在浏览器上执行。
- XMLHttpRequest 只是实现 Ajax 的一种方式。
ajax工作原理:
- 简单来说,我们之前发的请求通过类似 form表单标签,a标签 这种方式,现在通过 运行js代码动态决定什么时候发送什么样的请求
- 通过运行JS代码发送的请求浏览器可以不用跳转页面 ,我们可以在JS代码中决定是否要跳转页面
- 通过运行JS代码发送的请求,接收到返回结果后,我们可以将结果通过dom编程渲染到页面的某些元素上,实现局部更新。
4.2 如何实现ajax请求
原生javascript方式进行ajax(了解):
<script>
function loadXMLDoc(){
var xmlhttp=new XMLHttpRequest();
// 设置回调函数处理响应结果
xmlhttp.onreadystatechange=function(){
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.getElementById("myDiv").innerHTML=xmlhttp.responseText;
}
}
// 设置请求方式和请求的资源路径
xmlhttp.open("GET","/try/ajax/ajax_info.txt",true);
// 发送请求
xmlhttp.send();
}
</script>
五 案例开发-日程管理-第四期
5.1 注册提交前校验用户名是否占用功能
客户端代码编写处理
- regist.html页面代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.ht{
text-align: center;
color: cadetblue;
font-family: 幼圆;
}
.tab{
width: 500px;
border: 5px solid cadetblue;
margin: 0px auto;
border-radius: 5px;
font-family: 幼圆;
}
.ltr td{
border: 1px solid powderblue;
}
.ipt{
border: 0px;
width: 50%;
}
.btn1{
border: 2px solid powderblue;
border-radius: 4px;
width:60px;
background-color: antiquewhite;
}
.msg {
color: gold;
}
.buttonContainer{
text-align: center;
}
</style>
<script>
// 校验用户名的方法
function checkUsername(){
// 定义正则
var usernameReg=/^[a-zA-Z0-9]{5,10}$/
var username =document.getElementById("usernameInput").value
var usernameMsgSpan =document.getElementById("usernameMsg")
if(!usernameReg.test(username)){
usernameMsgSpan.innerText="不合法"
return false
}
// 发送ajax请求校验用户名是否被占用
var request;
if(window.XMLHttpRequest){
request= new XMLHttpRequest();
}else{
request= new ActiveXObject("Microsoft.XMLHTTP");
}
request.onreadystatechange= function (){
// request.readyState == 4 代表请求结束,已经接收到响应结果
// request.status== 200 表示后端响应状态码是200
if(request.readyState == 4 && request.status== 200){
// 后端的响应的JSON字符串转换为前端的对象
var response =JSON.parse(request.responseText)
console.log(response)
// 判断业务码是否是200
if (response.code != 200){
usernameMsgSpan.innerText="已占用"
return false
}
}
}
// 设置请求方式,请求资源路径,是否为异步请求
request.open("GET",'/user/checkUsernameUsed?username='+username,true)
// 发送请求
request.send();
// 前面校验都通过
// usernameMsgSpan.innerText="OK"
// return true
}
// 校验密码的方法
function checkUserPwd(){
// 定义正则
var passwordReg=/^[0-9]{6}$/
var userPwd =document.getElementById("userPwdInput").value
var userPwdMsgSpan =document.getElementById("userPwdMsg")
if(!passwordReg.test(userPwd)){
userPwdMsgSpan.innerText="不合法"
return false
}
userPwdMsgSpan.innerText="OK"
return true
}
// 校验密码的方法
function checkReUserPwd(){
// 定义正则
var passwordReg=/^[0-9]{6}$/
var userPwd =document.getElementById("userPwdInput").value
var reUserPwd =document.getElementById("reUserPwdInput").value
var reUserPwdMsgSpan =document.getElementById("reUserPwdMsg")
if(!passwordReg.test(userPwd)){
reUserPwdMsgSpan.innerText="不合法"
return false
}
if(userPwd != reUserPwd){
reUserPwdMsgSpan.innerText="不一致"
return false
}
reUserPwdMsgSpan.innerText="OK"
return true
}
//表单提交时统一校验
function checkForm(){
return checkUsername() && checkUserPwd() && checkReUserPwd()
}
</script>
</head>
<body>
<h1 class="ht">欢迎使用日程管理系统</h1>
<h3 class="ht">请注册</h3>
<form method="post" action="/user/regist" onsubmit="return checkForm()">
<table class="tab" cellspacing="0px">
<tr class="ltr">
<td>请输入账号</td>
<td>
<input class="ipt" id="usernameInput" type="text" name="username" onblur="checkUsername()">
<span id="usernameMsg" class="msg"></span>
</td>
</tr>
<tr class="ltr">
<td>请输入密码</td>
<td>
<input class="ipt" id="userPwdInput" type="password" name="userPwd" onblur="checkUserPwd()">
<span id="userPwdMsg" class="msg"></span>
</td>
</tr>
<tr class="ltr">
<td>确认密码</td>
<td>
<input class="ipt" id="reUserPwdInput" type="password" onblur="checkReUserPwd()">
<span id="reUserPwdMsg" class="msg"></span>
</td>
</tr>
<tr class="ltr">
<td colspan="2" class="buttonContainer">
<input class="btn1" type="submit" value="注册">
<input class="btn1" type="reset" value="重置">
<button class="btn1"><a href="/login.html">去登录</a></button>
</td>
</tr>
</table>
</form>
</body>
</html>
服务端代码处理
- 添加公共的JSON数据响应格式类
package com.atguigu.schedule.common;
/**
* 业务含义和状态码对应关系的枚举
*
*/
public enum ResultCodeEnum {
SUCCESS(200,"success"),
USERNAME_ERROR(501,"usernameError"),
PASSWORD_ERROR(503,"passwordError"),
NOTLOGIN(504,"notLogin"),
USERNAME_USED(505,"userNameUsed")
;
private Integer code;
private String message;
private ResultCodeEnum(Integer code, String message) {
this.code = code;
this.message = message;
}
public Integer getCode() {
return code;
}
public String getMessage() {
return message;
}
}
package com.atguigu.schedule.common;
/**
* 全局统一响应的JSON格式处理类
*
*/
public class Result<T> {
// 返回码
private Integer code;
// 返回消息
private String message;
// 返回数据
private T data;
public Result(){}
// 返回数据
protected static <T> Result<T> build(T data) {
Result<T> result = new Result<T>();
if (data != null)
result.setData(data);
return result;
}
public static <T> Result<T> build(T body, Integer code, String message) {
Result<T> result = build(body);
result.setCode(code);
result.setMessage(message);
return result;
}
public static <T> Result<T> build(T body, ResultCodeEnum resultCodeEnum) {
Result<T> result = build(body);
result.setCode(resultCodeEnum.getCode());
result.setMessage(resultCodeEnum.getMessage());
return result;
}
/**
* 操作成功
* @param data baseCategory1List
* @param <T>
* @return
*/
public static<T> Result<T> ok(T data){
Result<T> result = build(data);
return build(data, ResultCodeEnum.SUCCESS);
}
public Result<T> message(String msg){
this.setMessage(msg);
return this;
}
public Result<T> code(Integer code){
this.setCode(code);
return this;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}
- 增加Jackson依赖
- 添加WEBUtil工具类
package com.atguigu.schedule.util;
import com.atguigu.schedule.common.Result;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.text.SimpleDateFormat;
public class WebUtil {
private static ObjectMapper objectMapper;
// 初始化objectMapper
static{
objectMapper=new ObjectMapper();
// 设置JSON和Object转换时的时间日期格式
objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
}
// 从请求中获取JSON串并转换为Object
public static <T> T readJson(HttpServletRequest request,Class<T> clazz){
T t =null;
BufferedReader reader = null;
try {
reader = request.getReader();
StringBuffer buffer =new StringBuffer();
String line =null;
while((line = reader.readLine())!= null){
buffer.append(line);
}
t= objectMapper.readValue(buffer.toString(),clazz);
} catch (IOException e) {
throw new RuntimeException(e);
}
return t;
}
// 将Result对象转换成JSON串并放入响应对象
public static void writeJson(HttpServletResponse response, Result result){
response.setContentType("application/json;charset=UTF-8");
try {
String json = objectMapper.writeValueAsString(result);
response.getWriter().write(json);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
- 用户名校验业务接口代码
/**
* SysUserController下,注册时校验用户名是否被占用的业务接口
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void checkUsernameUsed(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String username = req.getParameter("username");
SysUser registUser = userService.findByUsername(username);
//封装结果对象
Result result=null;
if(null ==registUser){
// 未占用,创建一个code为200的对象
result= Result.ok(null);
}else{
// 占用, 创建一个结果为505的对象
result= Result.build(null, ResultCodeEnum.USERNAME_USED);
}
// 将result对象转换成JSON并响应给客户端
WebUtil.writeJson(resp,result);
}
本文为学习笔记,所参考文章均已附上链接,若有疑问请私信!
创作不易,如果对你有点帮助的话麻烦点个赞支持一下!
新手小白,欢迎留言指正!