您的位置:首页 > 汽车 > 新车 > 异步交互技术Ajax-Axios

异步交互技术Ajax-Axios

2024/11/18 11:14:31 来源:https://blog.csdn.net/2202_75483664/article/details/141356854  浏览:    关键词:异步交互技术Ajax-Axios

目录

一、同步交互和异步交互

二、Ajax 

1.概述

2.如何实现ajax请求

三、异步传输数据乱码的问题

regist.html页面代码

 服务端代码处理

四、Axios

1. Axios的基本使用

(1)引入Axios文件

(2)使用Axios发送请求,并获取响应结果。

2.案例

3.请求方法的别名(推荐用这个,简单)


一、同步交互和异步交互

同步交互:在同步交互中,参与的各方在同一时间进行交流。请求一项操作后,发起方必须等待响应才能继续进行下一步操作

异步交互:在异步交互中,参与的各方可以在不同的时间进行交流。发起方发送请求后,可以继续进行其他操作,而不必等待响应。

二、Ajax 

1.概述

Ajax是如何实现异步交互的?

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

  • AJAX 不是新的编程语言,而是一种使用现有标准的新方法。

  • AJAX 最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。

  • AJAX 不需要任何浏览器插件,但需要用户允许 JavaScript 在浏览器上执行。

  • XMLHttpRequest 只是实现 Ajax 的一种方式。

简单来说,我们之前发的请求通过类似 form表单标签,a标签 这种方式,现在通过 运行js代码动态决定什么时候发送什么样的请求

通过运行JS代码发送的请求浏览器可以不用跳转页面 ,我们可以在JS代码中决定是否要跳转页面

通过运行JS代码发送的请求,接收到返回结果后,我们可以将结果通过dom编程渲染到页面的某些元素上,实现局部更新

2.如何实现ajax请求

 原生javascript方式进行ajax(了解):

<script>function loadXMLDoc(){// 创建XMLHttpRequest对象var request=new XMLHttpRequest();// 设置回调函数处理响应结果// request.readyState  1 2 3 4(只需要知道4表示收到服务器的响应)// request.status		响应状态码响应行状态码request.onreadystatechange=function(){if (request.readyState==4 && request.status==200){document.getElementById("myDiv").innerHTML=request.responseText;}}// 设置请求方式和请求的资源路径request.open("GET","/try/ajax/ajax_info.txt",true);// 发送请求request.send();}
</script> 

三、异步传输数据乱码的问题

由于Ajax由原生js接收响应数据解码的问题,可能会出现乱码的现象,一般标准的规定是将传输的数据用JSON数据串传输。 

比如下面的场景,一个注册页面,姓名的验证问题

前端页面要将后端响应的数据(JSON串)转发为JSON对象

后端要将数据存到一个对象,将对象转发为JSON串响应回去

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").valuevar 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  表示后端响应状态码是200if(request.readyState == 4  && request.status== 200){// 后端的响应的JSON字符串转换为前端的对象var response =JSON.parse(request.responseText)console.log(response)//  判断业务码是否是200if (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").valuevar 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").valuevar reUserPwd =document.getElementById("reUserPwdInput").valuevar 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工具类  (后面SpringMVC框架会提供方法)

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;// 初始化objectMapperstatic{objectMapper=new ObjectMapper();// 设置JSON和Object转换时的时间日期格式objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));}// 从请求中获取JSON串并转换为Objectpublic 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);}

四、Axios

上述原生的Ajax请求的代码编写起来还是比较繁琐的,所以接下来我们学习一门更加简单的发送Ajax请求的技术Axios 。Axios是对原生的AJAX进行封装,简化书写。Axios官网是:https://www.axios-http.cn

1. Axios的基本使用

(1)引入Axios文件

就是一个js文件,可以到官网下载。

<script src="js/axios-0.18.0.js"></script>

(2)使用Axios发送请求,并获取响应结果。

官方提供的api很多,此处给出2种,如下  

发送 get 请求

axios({method:"get",url:"http://localhost:8080/ajax-demo1/aJAXDemo1?username=zhangsan"
}).then(function (resp){alert(resp.data);
})

 发送 post 请求

axios({method:"post",url:"http://localhost:8080/ajax-demo1/aJAXDemo1",data:"username=zhangsan"
}).then(function (resp){alert(resp.data);
});

axios()是用来发送异步请求的,小括号中使用 js的JSON对象传递请求相关的参数:

  • method属性:用来设置请求方式的。取值为 get 或者 post。

  • url属性:用来书写请求的资源路径。如果是 get 请求,需要将请求参数拼接到路径的后面,格式为: url?参数名=参数值&参数名2=参数值2。

  • data属性:作为请求体被发送的数据。也就是说如果是 post 请求的话,数据需要作为 data 属性的值。

then() 需要传递一个匿名函数。我们将 then()中传递的匿名函数称为 回调函数,意思是该匿名函数在发送请求时不会被调用,而是在成功响应后调用的函数。而该回调函数中的 resp 参数是对响应的数据进行封装的对象,通过 resp.data 可以获取到响应的数据。

2.案例

向后端请求数据:

后端实现

查询所有员工信息服务器地址:http://yapi.smart-xwork.cn/mock/169327/emp/list

根据员工id删除员工信息服务器地址:http://yapi.smart-xwork.cn/mock/169327/emp/deleteById

 前端实现

  <!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Ajax-Axios</title><script src="js/axios-0.18.0.js"></script></head><body><input type="button" value="获取数据GET" onclick="get()"><input type="button" value="删除数据POST" onclick="post()"></body><script>function get(){//通过axios发送异步请求-getaxios({method: "get",url: "http://yapi.smart-xwork.cn/mock/169327/emp/list"}).then(result => {console.log(result.data);})}function post(){// 通过axios发送异步请求-postaxios({method: "post",url: "http://yapi.smart-xwork.cn/mock/169327/emp/deleteById",data: "id=1"}).then(result => {console.log(result.data);})}</script></html>

 浏览器F12获取,然后分别点击2个按钮,查看控制台效果如下:

3.请求方法的别名(推荐用这个,简单)

Axios还针对不同的请求,提供了别名方式的api,具体如下:

方法描述
axios.get(url [, config])发送get请求
axios.delete(url [, config])发送delete请求
axios.post(url [, data[, config]])发送post请求
axios.put(url [, data[, config]])发送put请求

在上述的案例中,我们可以将get请求代码改写成如下:

axios.get("http://yapi.smart-xwork.cn/mock/169327/emp/list").then(result => {console.log(result.data);
})

post请求改写成如下:

axios.post("http://yapi.smart-xwork.cn/mock/169327/emp/deleteById","id=1").then(result => {console.log(result.data);
})

 

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com