【JavaWeb】Ajax详解
一、什么是 Ajax?
Ajax 即 Asynchronous Javascript And XML(异步 JavaScript 和 XML),是一种用于创建快速动态网页的技术,通过在后台与服务器进行少量数据交换,Ajax 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新
二、同步与异步
- 同步: 发送一个请求,需要等待响应返回,然后才可以发送下一个请求,如果该请求没有响应,则需等待
- 异步:发送一个请求,不需要等待响应返回,随时可以发送下一个请求
三、Ajax 工作原理
Ajax 的目的是提高用户体验,较少网络数据的传输量。Ajax 在客户端和服务器之间加了一个中间层,使客户端操作与服务器响应异步化,一些数据验证和数据处理交给 Ajax 引擎自己来做,而不需要交给服务器,只有确定需要从服务器读取新数据时才会通过 Ajax 引擎代为向服务器提交请求
四、Ajax 实现步骤
创建 XMLHttpRequest 核心对象 xhr
1 | const xhr = new XMLHttpRequest(); |
通过 XMLHttpRequest 对象的 open()方法给当前对象提供访问方式、URL 等与服务端建立连接
1 2 3 4 5 6 | xhr.open(method, url, [async][, user][, password]) //method:表示当前的请求方式,常见的有GET、POST //url:服务端地址 //async:布尔值,表示是否异步执行操作,默认为true //user: 可选的用户名用于认证用途;默认为null //password: 可选的密码用于认证用途,默认为null |
通过 XMLHttpRequest 对象的 send()方法发送给服务端
1 2 3 4 | xhr.send([body]) //body: 在 xhr 请求中要发送的数据体,如果不传递数据则为 null 如果使用GET请求发送数据的时候,需要注意如下: //将请求数据添加到open()方法中的url地址中 //发送请求数据中的send()方法中参数设置为null |
接受返回值并处理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | request.onreadystatechange = function(e){ if (request.readyState === 4){ // 整个请求过程完毕 if (request.status >= 200 && request.status <= 300){ console.log(request.responseText) // 服务端返回的结果 } else if (request.status >=400){ console.log( "错误信息:" + request.status) } } } //readyState 属性一共有5个值,分别表示不同的请求响应阶段: //0: 还未创建请求,即未调用 open() 方法 //1: 已调用 open() 方法,但未发送 send() 方法 //2: 已调用 send() 方法,但未接收到响应 //3: 已接收到部分响应 //4: 已接收到全部的响应 |
五、Ajax 应用场景
- 动态加载内容:Ajax 可以在不刷新整个页面的情况下,通过异步请求从服务器获取数据并动态更新页面的部分内容,从而实现更流畅的用户体验
- 表单验证:Ajax 可以在不刷新整个页面的情况下,实时验证表单数据的合法性(如手机号、唯一性校验)并提供反馈信息
- 搜索建议:当用户在搜索框中输入内容时,Ajax 可以在输入框下方实时显示相关的搜索建议,帮助用户更快速地找到自己需要的信息
- 购物车更新:Ajax 可以在不刷新整个页面的情况下,实时更新购物车中的商品数量以及总价等信息
- 实时聊天:Ajax 可以实现与服务器的实时通信,让用户在不刷新页面的情况下,实时接收到其他用户的消息(如直播评论、点赞、礼物等)
六、Ajax 常见问题
1. 缓存问题
在一些浏览器中存在缓存机制,Ajax 只会发送一次请求,剩余请求则不会再发送给浏览器,而是直接读取缓存中的数据
解决方案:浏览器缓存是通过 URL 地址记录,只需更改 URL 地址即可解决缓存问题,xhr.open("get","/demo?t="+Date.now())
2. 跨域问题
当一个页面向另一个不同域名 / 不同协议 / 不同端口的页面请求资源时,因为浏览器的同源策略,会产生跨域问题
解决方案:
- 后台 Http 请求转发
- 后台配置 Cors
- 使用 SpringCloud 网关
- 使用 Nginx 转发
3. 请求超时与网络异常
当请求时间过长或网络出现问题时,可单独做一些特殊处理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | btn.addEventListener( 'click' , function(){ const xhr = new XMLHttpRequest(); //超时时间设置为2s xhr.timeout = 2000; //超时处理 xhr.ontimeout = function(){ // 超时相关操作 } //网络异常处理 xhr.onerror = function(){ // 网络异常相关操作 } xhr.open( "GET" , 'http://127.0.0.1:8080/demo' ); xhr.send(); xhr.onreadystatechange = function(){ if (xhr.readyState === 4){ if (xhr.status >= 200 && xhr.status< 300){ result.innerHTML = xhr.response; } } } }) |
4. 取消请求
当请求发出但并未响应时,可通过 abort()取消请求
1 2 3 4 5 6 7 8 9 10 11 | const btns = document.querySelectorAll( 'button' ); let x = null ; btns[0].onclick = function(){ x = new XMLHttpRequest(); x.open( "GET" , 'http://127.0.0.1:8080/demo' ); x.send(); } // 取消请求 btns[1].onclick = function(){ x.abort(); } |
七、常见 Ajax 三种请求方式
1.jQuery 请求
jQuery 是⼀个优秀的 js 框架,对 JS 原⽣的 Ajax 进⾏了封装,封装后的 Ajax 的操作⽅法更简洁,功能更强⼤,jQuery 三种常见请求方式:
请求方式 | 语法 |
Ajax 请求 | $.ajax([settings]) |
GET 请求 | $.get(url,[data],[callback],[type]) |
POST 请求 | $.post(url,[data],[callback],[type]) |
参数名称 | 描述 |
url | 请求地址 |
data | 请求参数 |
type | 请求类型 |
async | 布尔类型 true/false,代表异步和同步,默认为 true |
dataType | 回传数据类型 |
success | 成功回调函数 |
error | 失败回调函数 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | // Ajax请求 $.ajax({ url: "" , data:{}, type: "post/get" , async: true , dataType: "text" , success:function(obj){ }, error:function(){ } }) // GET请求 $( "button" ).click(function(){ $. get ( "demo_test.asp" ,function(data,status){ alert( "Data: " + data + "\nStatus: " + status); }); }); // POST请求 $( "button" ).click(function(){ $.post( "demo_test_post.asp" , { name: "Donald Duck" , city: "Duckburg" }, function(data,status){ alert( "Data: " + data + "\nStatus: " + status); }); }); |
2.Axios 请求
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | //配置 baseURL axios.defaults.baseURL = 'http://127.0.0.1:8080' ; btns[2].onclick = function () { axios({ //请求方法 method: 'POST' , //url url: '/axios-server' , //url参数 params : { vip: 10, level: 30 }, //头信息,此部分如果使用自定义的头信息,需要服务端进行相应修改,正常不设置 headers: { a: 100, b: 200 }, //请求体参数 data: { username: 'admin' , password: 'admin' } }).then(response => { //响应状态码 console.log(response.status); //响应状态字符串 console.log(response.statusText); //响应头信息 console.log(response.headers); //响应体 console.log(response.data); }) } |
3.Fetch 请求
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | btn.onclick = function () { fetch( 'http://127.0.0.1:8080/fetch-server?vip=10' , { //请求方法 method: 'POST' , //请求头 headers: { name: 'aodi' }, //请求体 body: 'username=admin&password=admin' }).then(response => { // return response.text(); return response.json(); }).then(response => { console.log(response); }); } |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步