一、AJAX 概述1.1 什么是 AJAXAJAX 全称 Asynchronous JavaScript and XML即异步 JavaScript 和 XML。它并不是一门新的编程语言而是一种将现有技术组合在一起使用的开发模式。通过 AJAX浏览器可以在不刷新整个页面的情况下与服务器进行少量数据交换从而局部更新页面内容。2005 年 Google 在 Gmail 和 Google Maps 中大规模应用 AJAX 后这项技术迅速普及如今几乎所有现代 Web 应用都离不开它。1.2 传统 Web 应用与 AJAX 应用的对比传统 Web 应用无 AJAX用户点击链接或提交表单 → 浏览器将整个页面数据发送给服务器 → 服务器处理并生成全新的完整 HTML 页面 → 浏览器接收并重新加载渲染整个页面。在这个过程中用户会看到页面闪烁、白屏且必须等待完整的页面传输完成交互体验较差。AJAX 应用用户触发操作如输入文字、点击按钮 → JavaScript 在后台通过 XMLHttpRequest 对象异步发送请求仅携带必要数据 → 服务器处理并只返回需要更新的数据片段通常是 JSON 或纯文本 → JavaScript 回调函数接收数据使用 DOM 操作只修改页面中对应的部分如一个 span 标签的内容。整个过程页面无刷新用户感觉非常流畅。1.3 AJAX 的核心优势优势一页面无刷新用户体验好。用户不会看到页面闪烁操作感觉更加连贯。优势二异步通信不阻塞用户操作。在请求发送期间用户仍然可以滚动页面或点击其他元素。优势三减少数据传输量。只传输必要的数据而不是整个 HTML 页面节省带宽。优势四前后端分离的基础。现代前端框架Vue、React 等都基于 AJAX 或 Fetch 与后端交互。二、AJAX 工作原理整个 AJAX 交互过程可以分解为以下 6 个步骤第 1 步用户在浏览器中触发某个事件例如输入框失去焦点、点击按钮、页面滚动等。第 2 步浏览器中的 JavaScript或 jQuery创建一个 XMLHttpRequest 对象jQuery 内部封装了这一步并配置请求参数请求的 URL、方法GET/POST、是否异步默认为 true、要发送的数据等。第 3 步JavaScript 将请求发送给服务器。此时浏览器不会等待服务器响应用户仍然可以正常操作页面这就是“异步”的核心含义。第 4 步服务器接收到请求进行业务处理例如查询数据库、验证身份、计算数据等。第 5 步服务器将处理结果以某种格式常见的有 JSON、XML、纯文本返回给浏览器。第 6 步浏览器中的 JavaScript 通过预先定义好的回调函数success 或 error接收到服务器返回的数据然后使用 DOM 操作例如修改元素的 innerHTML 或文本内容来更新页面中的指定区域整个过程不刷新页面。三、jQuery 中的 AJAX —— $.ajax() 方法精讲jQuery 封装了浏览器原生 XMLHttpRequest 对象提供了简洁、跨浏览器的 AJAX 接口。其中最核心、最灵活的方法就是 $.ajax()。3.1 基本语法结构$.ajax({ url: 服务器地址, type: 请求方式get/post, data: { 参数名1: 值1, 参数名2: 值2 }, dataType: 预期返回的数据类型, success: function(data) { // 请求成功时执行的代码 }, error: function(xhr, status, error) { // 请求失败时执行的代码 } });3.2 最常用参数详解1url类型String必填。说明请求的目标地址。可以是绝对路径或相对路径。建议使用相对路径并注意部署时的上下文路径。2type类型String默认 get。说明HTTP 请求方法。常用 get 和 post。也可以使用 put、delete 等 RESTful 方法但部分浏览器可能不支持。3async类型Boolean默认 true。说明是否异步发送请求。强烈建议保持 true若设为 false 会阻塞浏览器导致页面卡顿用户体验极差。4data类型Object 或 String。说明发送给服务器的数据。如果是对象jQuery 会自动序列化为 key1value1key2value2 的格式。例如 { username: admin } 会变为 usernameadmin。GET 请求时数据会附加在 URL 后面POST 请求时放在请求体中。5dataType类型String默认自动推断。说明预期服务器返回的数据类型。常用值有text —— 纯文本html —— HTML 字符串json —— JSON 格式最常用前端可直接解析为对象xml —— XML 文档script —— JavaScript 代码如果不指定jQuery 会根据响应的 MIME 类型自动判断。6success类型Function。说明请求成功时调用的回调函数。接收两个参数第一个参数 data 是服务器返回的数据已根据 dataType 处理。第二个参数 textStatus 是状态描述字符串。函数内部的 this 指向当前 AJAX 请求的配置对象。7error类型Function。说明请求失败时调用的回调函数。接收三个参数xhr —— XMLHttpRequest 对象status —— 错误状态描述如 timeout、error、aborterrorThrown —— 捕获的异常对象可选通常在此函数中给用户友好提示并记录日志。8timeout类型Number单位毫秒。说明设置请求超时时间。如果超过该时间未收到响应将触发 error 回调并且 status 为 timeout。9cache类型Boolean默认 true当 dataType 为 script 时默认为 false。说明是否缓存请求结果。若设为 falsejQuery 会在 URL 后追加一个随机参数防止浏览器缓存。10beforeSend类型Function。说明发送请求之前调用的函数可以在此修改 XMLHttpRequest 对象如添加自定义请求头。如果该函数返回 false则取消本次请求。11complete类型Function。说明请求完成后无论成功还是失败调用的回调函数。参数为 xhr 和状态字符串。12contentType类型String默认 application/x-www-form-urlencoded; charsetUTF-8。说明发送数据到服务器时的内容编码类型。如果需要发送 JSON 数据可以改为 application/json。13processData类型Boolean默认 true。说明是否将 data 对象自动转换为字符串。当发送文件或 FormData 时需要设为 false。3.3 其他不常用参数jsonp用于跨域 JSONP 请求时回调函数名的替换。username / passwordHTTP 认证的用户名和密码。ifModified仅在服务器数据改变时获取新数据基于 Last-Modified 头。global是否触发全局 AJAX 事件ajaxStart、ajaxStop 等。四、实战案例用户名实时验证本案例模拟用户注册时当输入用户名后自动检测是否已被占用并实时给出提示。我们假设 admin 和 zhangsan 已被占用其他用户名可用。4.1 需求描述与功能拆解用户在输入框中输入用户名输入时自动触发验证同时失去焦点时也验证。前端发送异步请求到后端携带用户名。后端判断用户名是否已存在返回 exist 或 not exist。前端根据返回值在输入框右侧显示不同颜色和文字的提示信息。整个过程页面不能刷新且要对用户频繁输入进行防抖优化避免过多请求。4.2 后端 Servlet 实现创建一个 Java Web 项目编写一个 Servlet映射地址为 /ajax/checkUsername。import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class CheckUsernameServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 设置请求和响应的编码防止中文乱码 request.setCharacterEncoding(UTF-8); response.setCharacterEncoding(UTF-8); response.setContentType(text/plain;charsetUTF-8); // 获取客户端传递的用户名参数 String username request.getParameter(username); String result; // 模拟数据库查询假设 admin 和 zhangsan 已被占用 if (username null || username.trim().isEmpty()) { result empty; } else if (admin.equals(username.trim()) || zhangsan.equals(username.trim())) { result exist; } else { result not exist; } // 将结果写回客户端 response.getWriter().write(result); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } }同时在 web.xml 中配置 Servlet 映射或使用 WebServlet 注解若 Servlet 3.0servlet servlet-nameCheckUsernameServlet/servlet-name servlet-classcom.example.CheckUsernameServlet/servlet-class /servlet servlet-mapping servlet-nameCheckUsernameServlet/servlet-name url-pattern/ajax/checkUsername/url-pattern /servlet-mapping4.3 前端页面实现本页面采用以下改进措施使用 $(document).ready 确保 DOM 加载完成后再绑定事件。同时监听 input 事件实时输入和 blur 事件失去焦点。使用防抖debounce控制请求频率减少无效网络调用。阻止表单默认提交避免页面刷新。显示加载状态、成功状态、错误状态并用不同颜色区分。前端基础校验空值、长度。错误处理区分超时和网络错误。完整 HTML 代码如下!DOCTYPE html html langzh-CN head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 title用户名实时验证AJAX 完整版/title !-- 使用 jQuery CDN若无法联网可替换为本地文件 -- script srchttps://cdn.jsdelivr.net/npm/jquery1.12.4/dist/jquery.min.js/script style body { font-family: Microsoft YaHei, PingFang SC, Arial, sans-serif; background: #f0f2f5; margin: 0; padding: 40px 20px; display: flex; justify-content: center; align-items: center; min-height: 100vh; } .container { background: #fff; max-width: 480px; width: 100%; padding: 35px 40px 40px; border-radius: 12px; box-shadow: 0 4px 20px rgba(0,0,0,0.08); } h2 { text-align: center; color: #1a1a2e; margin-bottom: 30px; font-weight: 500; } .form-group { margin-bottom: 22px; position: relative; } .form-group label { display: inline-block; width: 80px; font-weight: 500; color: #333; } .form-group input { padding: 10px 14px; border: 1px solid #d9d9d9; border-radius: 6px; width: 220px; font-size: 14px; transition: border-color 0.2s; box-sizing: border-box; } .form-group input:focus { border-color: #1890ff; outline: none; box-shadow: 0 0 0 2px rgba(24,144,255,0.2); } .msg { margin-left: 12px; font-size: 14px; font-weight: 500; display: inline-block; min-width: 120px; } .msg.loading { color: #faad14; } .msg.success { color: #52c41a; } .msg.error { color: #ff4d4f; } .hint { font-size: 12px; color: #888; margin-top: 6px; margin-left: 90px; } .btn-submit { background: #1890ff; color: #fff; border: none; padding: 12px 20px; border-radius: 6px; font-size: 16px; cursor: pointer; width: 100%; transition: background 0.2s; margin-top: 10px; } .btn-submit:hover { background: #40a9ff; } .btn-submit:active { background: #096dd9; } /style /head body div classcontainer h2用户注册 · 实时验证/h2 form idregForm div classform-group label forusername用户名/label input typetext idusername placeholder至少3个字符 autocompleteoff / span classmsg idmsg等待输入.../span div classhint输入后自动验证admin 或 zhangsan 已被占用/div /div div classform-group label forpassword密码/label input typepassword idpassword placeholder6-20位字母或数字 / /div button typesubmit classbtn-submit注册演示拦截/button /form /div script $(document).ready(function() { // ---------- 防抖函数 ---------- function debounce(fn, delay) { var timer null; return function() { var context this; var args arguments; clearTimeout(timer); timer setTimeout(function() { fn.apply(context, args); }, delay); }; } // ---------- 核心验证函数 ---------- function doValidate() { var $input $(#username); var $msg $(#msg); var username $.trim($input.val()); // 1. 前端非空校验 if (username ) { $msg.text(用户名不能为空).removeClass(loading success).addClass(error); return; } // 2. 长度校验 if (username.length 3) { $msg.text(至少3个字符).removeClass(loading success).addClass(error); return; } // 3. 显示加载状态 $msg.text(验证中...).removeClass(success error).addClass(loading); // 4. 发送 AJAX 请求注意 URL 请根据实际部署调整 // 若项目部署在根路径则 /ajax/checkUsername // 若有上下文路径如 /myapp则改为 /myapp/ajax/checkUsername $.ajax({ url: /ajax/checkUsername, type: POST, data: { username: username }, dataType: text, timeout: 5000, // 5秒超时 success: function(data) { if (data exist) { $msg.text(该用户名已被占用请更换).removeClass(loading).addClass(error); } else if (data not exist) { $msg.text(该用户名可用 ✓).removeClass(loading).addClass(success); } else if (data empty) { $msg.text(用户名不能为空).removeClass(loading).addClass(error); } else { $msg.text(服务器返回异常).removeClass(loading).addClass(error); console.warn(未知返回数据, data); } }, error: function(xhr, status, errorThrown) { if (status timeout) { $msg.text(请求超时请检查网络).removeClass(loading).addClass(error); } else if (status error) { $msg.text(网络连接失败请重试).removeClass(loading).addClass(error); } else { $msg.text(验证失败请稍后重试).removeClass(loading).addClass(error); } console.error(AJAX错误, status, errorThrown); } }); } // 5. 防抖包装输入时延迟300ms避免频繁请求 var debouncedValidate debounce(doValidate, 300); // 6. 绑定事件 $(#username).on(input, debouncedValidate); // 输入时防抖验证 $(#username).on(blur, doValidate); // 失去焦点时立即验证不防抖 // 7. 阻止表单默认提交演示用 $(#regForm).on(submit, function(e) { e.preventDefault(); alert(表单提交已被拦截演示 AJAX 验证实际可在此执行最终提交); }); // 8. 初始化提示可选 $(#msg).text(输入后自动验证); }); /script /body /html