Ajax异步请求解析,打通前后端,看这一篇就够了

发布时间:2026/7/22 16:23:15
Ajax异步请求解析,打通前后端,看这一篇就够了 目录一. 异步请求举例二. Ajax 异步请求详解2.1 Ajax 简介2.2 XMLHttpResponse对象的属性和方法2.3 ajax() 的使用方式三. Ajax 请求代码举例3.1 确认用户名是否被占用例子3.1.1 用户注册界面展示3.1.2 前端用户注册表单代码3.1.3 前端 JavaScript 发送 Ajax 请求的代码3.1.4 后端代码3.2 修改用户信息举例3.2.1 浏览器页面效果展示3.2.2 用户表单代码3.2.3 前端 JavaScript 代码3.2.4 后端 Controller 层接口代码3.2.5 业务层代码代码3.2.6 DAO层代码Mapper层代码3.3 代码仓库及相关视频四. Ajax的优缺点一. 异步请求举例例子一比如用户注册完毕之后点击了提交按钮提交表单浏览器会发送HTTP请求将用户填写的数据提交到后端服务器而用户在注册的时候填写用户名时输入一个用户名有时候会显示该用户名已被占用请选择另外一个那么它是怎么知道这个用户名已经存在的了呢其实就是通过异步请求来完成的当用户输入完毕用户名之后它会在不影响用户使用的情况下不用刷新网页向服务器发送异步HTTP请求向数据库表中查询当前用户名是否已经存在。如果返回值为NULL则说明该用户名尚未被占用如果返回值不为NULL则说明该用户名已被其他用户占用不能使用此用户名例子二比喻电商网站我们会发现页面上的数据都是在不断变化的热销商品在不断变化那么它是如何做到的呢其实也可以通过异步请求来完成用户在浏览商品的时候页面的后台在不断的向服务器发送HTTP请求查询数据库中最新的商品数据返回给前端前端浏览器解析返回的数据在展示给用户。二. Ajax 异步请求详解2.1 Ajax 简介现在来看Ajax 并不是一个很新的技术但是它的异步请求思想还是直接我们去借鉴和思考的。现在的很多前端框架归根结底还是封装的 JavaScript 代码Ajax 也不例外。实质上Ajax 只是 JQuery 框架封装的一个函数也可以称之为 $.ajax() 函数通过调用 ajax() 函数加载发送异步请求JavaScript 提供了一个对象XHR(XMLHttpResponse)它就是 Ajax 的核心对象发送请求以及接收服务器数据的返回全靠它。此外现代浏览器全都内置了 XMLHttpResponse 对象所以都支持的 XMLHttpResponse 对象数据。说白了就一句话Ajax 是一种异步无刷新发送网络请求的技术。2.2 XMLHttpResponse对象的属性和方法1XMLHttpResponse 属性属性描述status返回请求的状态号200:OK403:Forbidden404:Not FoundstatusText返回状态文本(比如OK或Not Found)responseText以字符串返回响应数据responseXML以 XML 数据返回响应数据readyState保存 XMLHttpResponse 的状态。0:请求未初始化1:服务器连接已建立2:请求已收到3:正在处理请求4:请求已完成且响应已就绪onreadystatechange定义当 readyState 属性变化发生变化时被调用的函数2XMLHttpResponse 方法方法描述send()向服务器发送GET请求send(String)向服务器发送POST请求open(methodurlasyncuserspsw)method规定请求的方法url请求路径GET和POSTuser可选的用户名称psw可选的密码sendRequestHeader()向要发送的报头添加标签/值对abort()取消当前请求getAllResponseHeaders()返回头部信息getResponseHeader()返回特定的头部信息2.3 ajax() 的使用方式ajax() 函数的使用方式就是直接写 $.ajax(参数...)参数需要传递一个方法体众所周知JavaScript 方法体如下代码所示function(){ 函数体... }所以 ajax() 函数的语法如下$.ajax(function(){ 函数体... })但是ajax 需要我们传入的是一个方法方法体也就是大括号和大括号内不的内容即{函数体...}。因此我们实际使用的时候通常会将 function() 省略不写就变成了下面这种格式$.ajax({ 函数体... })此外函数体包含以下几个参数参数与参数之间使用逗号进行分割每一组参数之间使用:冒号进行分割并且称它们的顺序没有要求谁写在最上面都可以。如下是一种常用的书写方式$.ajax({ url:, type:, async:, data:, dataType:, contentType:, success:function(result){ //result:服务器响应的数据 //处理服务器响应的数据 }, error:function(){ //处理请求失败的情况 } })各个参数的含义如下表格所示参数功能描述url表示请求的地址(url地址)不能包含参数列表的内容。url举例http://localhost:8080/users/regtype请求类型(常用请求类型为GET和POST)。type举例 type:POSTasync是否同步刷新数据默认为 ture 开启状态data向指定的URL地址提交的数据。举例如 data:usernametompassword123dataType提交的数据类型一般都是指定为JSON格式举例如 dataType:jsoncontentType设置请求头success服务器正常响应客户端时会自动调用success参数的方法将服务器返回的数据以参数的形式传递给这个方法的参数上error当服务器为正常响应客户端时会自动调用error参数的方法将服务器返回的数据以参数的形式传递给这个方法的参数上三. Ajax 请求代码举例3.1 确认用户名是否被占用例子3.1.1 用户注册界面展示我们都知道很多系统中用户昵称都是唯一的特别是在游戏中所以我们做一个用户昵称确认的方法当用户输入玩用户名称之后校验用户名是否已被占用当我们启动项目后在用户注册界面用户只要在文本框内输入用户名注册再点击其它地方就会触发失焦事件发送HTTP请求到后端去查询用户希望注册的用户名是否已经存在效果如下图所示当然了在实际公司开发的项目中通常不会采用弹窗的方式提示用户而是在用户名一行下面显示红色字体进行提示我们这里就不做那么麻烦了主要是为了让同学们知道这种需求的思路设计。3.1.2 前端用户注册表单代码form idform-reg classform-horizontal roleform !--用户名-- div classform-group label classcol-md-3 control-label名字/label div classcol-md-8 input idusername nameusername typetext classform-control placeholder请输入用户名 /div /div !--密码-- div classform-group label classcol-md-3 control-label 密码/label div classcol-md-8 input idpassword namepassword typetext classform-control placeholder请输入密码 /div /div !--确认密码-- div classform-group label classcol-md-3 control-label 确认密码/label div classcol-md-8 input typetext classform-control placeholder请再次输入密码 /div /div !--提交按钮-- div classform-group label classcol-md-3 control-label/label div classcol-md-8 input idbtn-reg classbtn btn-primary typebutton value立即注册 / span classpull-rightsmall已经有账号/smalla hreflogin.html登录/a/span /div /div /form3.1.3 前端 JavaScript 发送 Ajax 请求的代码// 用户输入用户名发送ajax请求确认是否已经存在 $(#username).blur(function () { $.ajax({ url: /users/getByUsername, type: get, dataType: json, data: { username: $(#username).val(), }, // 正确的格式 success:function (json) { if(json.code 200 json.data ! null){ // 提示用户该用户名已被占用 alert(该用户名已被占用) }else{ // 不做任何提示 alert(该用户名未被占用) } }, error:function (xhr) { alert(查询用户名时产生未知的异常 xhr.statusxhr.message); }, }); });3.1.4 后端代码// Controller 层接口代码 RequestMapping(value /getByUsername,method GET) public JsonResultUser getByUsername(String username){ User data userService.findByUsername(username); return new JsonResult(OK ,data); } // Service 层业务类代码 public User findByUsername(String username) { return userMapper.findByUsername(username); } // Dao 层数据访问层代码 User findByUsername(Param(username) String username); // Mapper 层SQL语句编写 select idfindByUsername resultTypecom.cy.store.entity.User select * from t_user where username #{username} /select3.2 修改用户信息举例3.2.1 浏览器页面效果展示我们只关注中间用户信息的模块用户登陆成功之后点击进入修改信息界面就会马上发送 Ajax 请求查询用户信息返回到前端前端再进行展示当用户修改完成信息之后点击修改按钮会再次发送 Ajax 请求将新的用户数据传递给后端服务器然后修改书库结果然后前端同步刷新用户数据根本不需要刷新浏览器页面非常快捷方便。3.2.2 用户表单代码设置表单 idform-change-info修改按钮 idbtn-change-info!--修改资料表单开始-- form idform-change-info classform-horizontal roleform div classform-group label classcol-md-2 control-label用户名/label div classcol-md-8 input classform-control idusername nameusername typetext /div /div div classform-group label classcol-md-2 control-label电话号码/label div classcol-md-8 input classform-control idphone namephone typetext /div /div div classform-group label classcol-md-2 control-label电子邮箱/label div classcol-md-8 input classform-control idemail nameemail typetext /div /div div classform-group label classcol-md-2 control-label性别/label div classcol-md-8 label classradio-inline input idgender-male typeradio namegender value1男 /label label classradio-inline input idgender-female typeradio namegender value0女 /label /div /div div classform-group div classcol-sm-offset-2 col-sm-10 input idbtn-change-info typebutton classbtn btn-primary value修改 / /div /div /form3.2.3 前端 JavaScript 代码既然用户修改信息进入用户信息页面必然会有旧的信息。所以我们需要先定义一个定义一个初始填充数据的请求正如下带代码所示然后再获取需该按钮并为其绑定单击事件单击之后发送 ajax 请求到后端修改数据script // 进入修改信息页面发送ajax请求先查询出已有的用户信息渲染到页面 $(document).ready(function () { $.ajax({ url: /users/getByUid, type: GET, dataType: json, success: function(json) { if (json.code 200) { $(#username).val(json.data.username); $(#email).val(json.data.email); $(#phone).val(json.data.phone); let radio json.data.gender 0 ? $(#gender-female): $(#gender-male); radio.prop(checked, true); } else { alert(修改失败); } }, error: function(xhr) { alert(修改失败 xhr.message); } }); }); // 用户点击修改按钮发送ajax请求修改用户信息 $(#btn-change-info).click(function (){ $.ajax({ url: /users/changeInfo, type: POST, dataType: json, data: $(#form-change-info).serialize(), success: function(json) { if (json.code 200) { alert(修改成功); location.href userdata.html; }else{ alert(修改失败); } }, error: function(xhr) { alert(修改失败 xhr.message); }, }); }); /script3.2.4 后端 Controller 层接口代码上述 Ajax 请求正是由后端的接口进行接收并处理/* 获取用户信息 */ RequestMapping(value /getByUid,method GET) public JsonResultUser getUserByUid(HttpSession session){ Integer uid getUidFromSession(session); User data userService.findByUid(uid); return new JsonResult(OK ,data); } /* 用户修改个人资料 */ RequestMapping(value /changeInfo, method POST) public JsonResultVoid changeInfo(User user,HttpSession session){ // user对象中要四个数据username,phone,email,gender Integer uid getUidFromSession(session); String username getUsernameFromSession(session); userService.changeInfo(uid,username,user); return new JsonResult(OK); }3.2.5 业务层代码代码Override public User findByUid(Integer id) { User result userMapper.findByUid(id); if (result null || result.getIsDelete() 1){ throw new UserNotFoundException(该用户不存在); } User user new User(); user.setUsername(result.getUsername()); user.setPhone(result.getPhone()); user.setEmail(result.getEmail()); user.setGender(result.getGender()); return user; } Override public void changeInfo(Integer id, String username, User user) { User result userMapper.findByUid(id); if (result null || result.getIsDelete() 1){ throw new UserNotFoundException(该用户不存在); } user.setUid(id); user.setModifiedUser(username); user.setModifiedTime(new Date()); Integer rows userMapper.updateInfoByUid(user); if (rows ! 1){ throw new UpdateException(更新时发生错误); } }3.2.6 DAO层代码Mapper层代码User findByUid(Param(uid) Integer uid); select idfindByUid resultTypecom.cy.store.entity.User select * from t_user where uid #{uid} /select Integer updateInfoByUid(User user); update idupdateInfoByUid update t_user set !--if表示条件判断标签test接收的是返回值为布尔类型的条件如果test结果为true则执行if标签内的语句-- if testphone!nullphone #{phone},/if if testemail!nullemail #{email},/if if testgender!nullgender #{gender},/if modified_user #{modifiedUser}, modified_time #{modifiedTime} where uid #{uid} /update3.3 代码仓库及相关视频小编这里举的代码例子也是从B站上学习的相关视频链接【SpringBoot项目实战完整版】SpringBootMyBatisMySQL电脑商城项目实战_哔哩哔哩_bilibili项目的中代码我已经存储到了自己的 Gitee 仓库中仓库已经公开小伙伴们可以自己拉取具体操作可以看项目MD文档适合SSM和SpringBoot小白同学做的一个前端项目。项目目前代码仍在持续更新过程中小编也会把自己学习和编写的代码推到仓库中小编主要也是为了学习 Ajax 发送请求到后端与后端交互这一知识点所以主要推送前端代码效果伙伴们也可以自己看视频自己敲一遍哦。store: 电脑商城项目源码包含前后端。四. Ajax的优缺点Ajax 的优点1可以无需刷新页面与服务器进行通信2允许根据用户事件来更新部分页面内容Ajax 的缺点1没有浏览历史不能回退2存在跨域问题(同源)有解决办法下文会讲到3SEO不友好