所有分类
  • 所有分类
  • 游戏源码
  • 网站源码
  • 单机游戏
  • 游戏素材
  • 搭建教程
  • 精品工具

Ajax实现异步加载数据实战教程|前端必学的异步交互核心技巧

Ajax实现异步加载数据实战教程|前端必学的异步交互核心技巧 一

文章目录CloseOpen

Ajax到底是啥?其实就是“偷偷”发请求的小助手

先跟你说个最直观的例子:你打开某电商APP的商品列表,往下翻的时候,底部会出现“加载中”,然后新商品自动冒出来,不用你点“下一页”,也不用刷新页面——这就是Ajax干的事。以前的网页要更新数据,得整个页面重新加载,就像你去超市买东西,要加瓶水得重新排一遍队;而Ajax就像超市里的“快速通道”,你喊一嗓子“加瓶水”,服务员直接给你递过来,不用重新排队。

那Ajax到底是怎么工作的?其实核心就两步:偷偷发请求偷偷更数据。比如你要加载下一页商品,Ajax会在后台给服务器发个请求(比如问“给我第2页的商品数据”),服务器返回数据后,Ajax再把这些数据插到页面里,全程不用刷新。

具体来说,Ajax有两个常用的“工具”:一个是老一点的XHR对象(XMLHttpRequest),另一个是新一点的Fetch API。我刚开始学的时候,先接触的是XHR,写起来有点麻烦——得创建XHR对象,然后用open()方法配置请求类型(GET/POST)和地址,再用send()发请求,还得监听onreadystatechange事件看请求状态。比如readyState等于4的时候才是请求完成,status等于200才是成功。我第一次写的时候,忘加onreadystatechange,结果请求发出去了,数据回来不知道怎么处理,盯着控制台看了半小时才反应过来:“哦,原来得等着状态变了才能处理数据啊!”

后来用Fetch API,就简单多了,一行代码就能发请求:fetch('https://api.com/goods'),然后用.then()链式调用处理返回的数据——先把响应转成JSON格式(res.json()),再把数据渲染到页面上。但Fetch有个小坑你得注意:它默认不处理HTTP错误,比如接口返回404(找不到资源)或者500(服务器错误),它不会自动触发catch(),得你自己判断res.ok是不是true。我上次做项目时没注意这个,接口返回404还在那渲染数据,结果页面显示“暂无数据”,差点被产品经理骂。后来我学聪明了,每次用Fetch都会加一句:if (!res.ok) throw new Error('请求失败啦'),这样就能把错误抓到catch()里,给用户弹个“加载失败”的提示。

对了,还有个更方便的工具叫Axios,是别人封装好的库,比XHR和Fetch都简单。比如发GET请求就是axios.get('apiurl'),发POST请求是axios.post('apiurl', {name: '苹果'}),它还能自动把数据转成JSON,自动处理跨域(如果后端允许的话),甚至能拦截请求和响应——比如每个请求都加个Authorization头(带用户token),或者每个响应都检查有没有登录失效。我现在做项目,90%的情况用Axios,因为它省了好多重复代码,比如以前用XHR得写十几行代码发请求,现在用Axios一行就搞定。

Ajax踩坑指南:我踩过的那些雷,你别再踩了

Ajax看着简单,但实际用的时候,容易踩各种坑——我帮人做项目的这两年,踩过的雷能凑成一本“避坑手册”,今天挑几个最常见的告诉你,省得你再掉进去。

坑1:跨域请求报错?先看后端有没有加“允许访问”的头

去年我做一个公众号的H5页面,调后端的用户信息接口,结果控制台一直报“Access-Control-Allow-Origin”错误,我以为是自己代码写错了,查了半天XHR的配置,没问题啊?后来问后端同事,他拍着脑袋说:“哦,我忘了加CORS头了!”——你知道吗?浏览器有个“同源策略”,就是说你的网页域名(比如https://www.xxx.com)和接口域名(比如https://api.xxx.com)不一样的话,浏览器会阻止请求,怕恶意网站偷数据。这时候得让后端在响应头里加一句Access-Control-Allow-Origin: https://www.xxx.com(或者*允许所有域名),这样浏览器才会放行。

要是后端没时间改,你也可以用nginx反向代理——把你的前端请求转发到后端接口,比如你前端请求https://www.xxx.com/api/goods,nginx把这个请求转到https://api.xxx.com/goods,这样浏览器以为是同源的,就不会拦了。我上次用nginx的时候,就加了几行配置:

location /api {

proxy_pass https://api.xxx.com;

}

改完重启nginx,跨域问题直接解决,比等后端改代码快多了。

坑2:请求发得太勤?用防抖节流“管管”它

你有没有做过实时搜索框?比如用户输“苹果”,输入过程中就显示相关搜索 要是用户输得快,每秒输5个字符,你每输一个字符就发一次请求,服务器得处理5次请求,既浪费资源,又容易让页面卡。我第一次做的时候没注意,结果接口请求频率太高,后端直接给我限速了,说“你这是在攻击服务器吧?”

后来我学了防抖节流——这俩都是“控制请求频率”的工具,帮你减少不必要的请求。防抖是“等用户停止操作一段时间再发请求”,比如用户输完字1秒没动,再发请求;节流是“每隔一段时间只能发一次请求”,比如不管用户怎么点,1秒内只能发一次。我做搜索框的时候,用了lodash的debounce函数,把请求延迟1秒,结果请求次数从每秒5次降到1次,服务器压力小了,用户也能实时看到 两全其美。

给你看段我写过的代码:

// 导入lodash的debounce

import { debounce } from 'lodash';

const searchInput = document.querySelector('#search');

// 用debounce包装搜索函数,延迟1秒执行

const debouncedSearch = debounce((keyword) => {

fetch(/api/search?keyword=${keyword})

.then(res => res.json())

.then(data => renderSuggestions(data));

}, 1000);

// 监听输入事件

searchInput.addEventListener('input', (e) => {

const keyword = e.target.value;

debouncedSearch(keyword);

});

这样用户输字再快,也只会在停止1秒后发请求,是不是很聪明?

坑3:数据没到就渲染?加个“加载中”再禁用按钮

我之前做一个“加载更多”按钮,点一下加载一页数据,结果没加loading状态,用户点了按钮没反应,以为没点到,就一个劲点,结果发了5次请求,服务器返回5页数据,页面一下冒出一堆重复商品。后来我学聪明了:点按钮的时候,先显示“加载中”的动画,再把按钮禁用(disabled=true),等请求回来再隐藏动画、启用按钮。这样用户就知道“正在加载”,不会乱点了。

再给你看段代码,是我现在常用的加载逻辑:

const loadMoreBtn = document.querySelector('#load-more');

const loading = document.querySelector('.loading');

loadMoreBtn.addEventListener('click', async () => {

// 显示加载中,禁用按钮

loading.style.display = 'block';

loadMoreBtn.disabled = true;

try {

// 发请求

const res = await fetch(/api/goods?page=${currentPage});

const data = await res.json();

// 渲染数据

renderGoods(data);

// 页码加1

currentPage++;

} catch (err) {

console.error('加载失败:', err);

alert('加载失败,请重试~');

} finally {

// 不管成功失败,都隐藏加载中,启用按钮

loading.style.display = 'none';

loadMoreBtn.disabled = false;

}

});

这样处理后,再也没出现过重复请求的问题,用户体验也好多了。

选对工具省一半力:我常用的Ajax工具对比

说了这么多,你肯定想问:到底用XHR、Fetch还是Axios?我帮你整理了个表格,对比了几个常用工具的优缺点,你根据项目选就行:

工具名称 语法复杂度 兼容性 错误处理 推荐场景
XHR对象 复杂 兼容所有浏览器(包括IE) 需手动监听状态变化 需要兼容老浏览器的项目
Fetch API 简洁 现代浏览器(IE不兼容) 需手动判断res.ok Vue/React等现代前端项目
Axios 非常简洁 兼容所有浏览器 自动捕获HTTP错误 大部分前端项目(推荐)

比如我现在做项目,90%的情况用Axios,因为它语法简单,还能自动处理错误——比如接口返回401(未登录),它会自动进catch(),我直接跳登录页就行,省了好多代码。要是项目要兼容IE,就用XHR或者Axios(Axios底层是XHR);要是做现代项目,比如Vue3、React18项目,用Fetch或者Axios都可以。

其实Ajax的核心就是“异步”——让请求在后台跑,不影响用户操作。我刚开始学的时候,总搞不清“异步”和“同步”的区别,后来想通了:同步就是“你得等我做完,才能做下一件事”,比如你打电话给朋友,得等他接了才能说话;异步就是“你先做别的,我做完告诉你”,比如发微信消息,发出去不用等回复,该干啥干啥,回复来了再看。

现在你再想Ajax的用法,是不是就清楚多了?比如做实时评论,用户点“提交”,Ajax把评论发给服务器,服务器返回成功后,直接把评论插到页面顶部,不用刷新;比如做表单验证,输入手机号时,Ajax实时检查手机号有没有被注册,不用点“提交”才知道。

最后跟你说个小技巧:写完Ajax代码,一定要用浏览器的“开发者工具”调试——打开Chrome的F12,点“网络”tab,就能看到请求的状态、响应数据,要是报错了,看“控制台”里的错误信息,比如跨域错误会显示“Access-Control-Allow-Origin”,请求失败会显示“404 Not Found”,这样排错特别快。我上次做项目时,请求一直失败,查网络面板发现接口地址写错了一个字母(把goods写成了good),改过来就好了。

你要是用Ajax做过项目,有没有踩过什么好玩的雷?或者按我讲的技巧试了,欢迎留言告诉我效果,咱们一起交流~


你问用Ajax怎么处理异步返回的数据啊?其实核心就一个——等请求“做完”了再动手。我刚开始学XHR的时候,踩过特别傻的坑:当时写了段代码,new了个XMLHttpRequest对象,open(‘GET’, ‘api/goods’),send()之后直接console.log(xhr.responseText),结果出来一空字符串。我盯着屏幕看了半天,“数据呢?服务器没给我发吗?”后来才反应过来,Ajax是“异步”的啊!就像你给朋友发微信问“有空吗?”,不能刚发出去就翻聊天记录找回复——得等朋友回了,你才能看到啊!

那XHR得怎么等呢?得给它加个“提醒”——onreadystatechange事件监听。这个事件会跟着请求的状态变:readyState从0到4,代表请求从“初始化”到“彻底完成”。等readyState变成4了,再看status码是不是200(服务器说“我给你数据了,没问题”),这时候才能用xhr.responseText或者xhr.responseJSON拿数据。比如我之前做用户信息页面,就是这么写的:xhr.onreadystatechange = function() { if (this.readyState === 4 && this.status === 200) { const user = JSON.parse(this.responseText); document.getElementById(‘username’).innerText = user.name; } }——你看,得等“双条件满足”,才能处理数据,急不得。

现在用Fetch或者Axios就省心多了,不用写那么多监听代码。比如Fetch,直接fetch(‘api/goods’),然后用.then()“接”数据:第一个then把服务器返回的响应转成JSON格式(res.json()),第二个then就拿到能用的数据了,直接插到页面里。我上周做实时搜索框的时候,就是这么搞的:用户输关键词,我用fetch(api/search?keyword=${input.value}),然后.then(res => res.json()).then(data => { 把data里的搜索 一条条插到页面的ul里 })——全程没写监听事件,简单得很。

还有更“顺嘴”的写法,用async/await。比如我现在做“加载更多”按钮,点击事件里写个async函数:async function loadMore() { const res = await fetch(api/goods?page=${currentPage}); if (!res.ok) throw new Error(‘加载失败’); const data = await res.json(); 把data里的商品渲染到页面底部 }——你看,就像“先等请求完成,再看有没有错,没错就拿数据”,跟说人话一样,不用记then()的顺序。对了,用Fetch的时候得注意,它默认不帮你处理HTTP错误——比如接口返回404或者500,它不会自动进catch(),得自己加个if (!res.ok) throw new Error(),不然页面会显示“暂无数据”,用户还以为是你代码错了呢。

其实不管用哪种工具,核心逻辑都一样:异步操作得“等”,不能急。就像你煮饺子,得等水开了、饺子浮起来,才能捞出来吃——早捞一步,肯定是生的啊!Ajax处理数据也是这道理,等请求走完流程,再动手,准没错。


XHR、Fetch和Axios应该选哪个?

可以根据项目需求选:如果要兼容IE等老浏览器,优先选XHR或Axios(Axios底层是XHR);如果是Vue3、React18这类现代项目,用Fetch或Axios都可以;要是想语法更简洁、自动处理HTTP错误(比如404、500),推荐Axios——它能统一配置请求头(比如加用户token),还能自动把响应转成JSON,省很多重复代码。

Ajax请求遇到跨域错误怎么办?

先找后端加CORS响应头(Access-Control-Allow-Origin),允许你的前端域名访问;要是后端没时间改,用Nginx反向代理更高效——把前端请求的转发到后端接口,这样浏览器会以为是“同源请求”,就不会拦截了。文章里提到的这两个方法,我自己做项目时都用过,基本能解决90%的跨域问题。

用Ajax时怎么处理异步返回的数据?

Ajax是“异步”的,得等请求完成再处理数据。比如用XHR要监听onreadystatechange事件,等readyState变成4(请求完成)、status是200(成功)时,才能用responseText或responseJSON拿数据;用Fetch或Axios更简单,用Promise的then()链式调用就行——比如fetch(url).then(res => res.json()).then(data => 把数据插到页面里),或者用async/await(像写同步代码一样):async函数里用await fetch(url),直接拿到响应再处理。

Ajax请求失败了怎么快速排查?

打开Chrome的开发者工具(按F12),先看“网络”标签:找到失败的请求,看“状态码”(比如404是接口地址错了,500是服务器崩了),看“请求URL”有没有拼错字母;再看“控制台”标签,里面会显示具体错误(比如跨域会提示“Access-Control-Allow-Origin”,请求超时会提示“timeout”)。我上次做项目时请求一直失败,就是在网络面板发现接口把“goods”写成了“good”,改过来就好了——这招比瞎猜管用多了。

原文链接:https://www.mayiym.com/45771.html,转载请注明出处。
0
显示验证码
没有账号?注册  忘记密码?

社交账号快速登录

微信扫一扫关注
如已关注,请回复“登录”二字获取验证码