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

AJAX原理及axios与fetch区别实例详解:一篇搞懂前端请求工具怎么选

AJAX原理及axios与fetch区别实例详解:一篇搞懂前端请求工具怎么选 一

文章目录CloseOpen

这篇文章就帮你把这些问题彻底理清楚。我们先从AJAX的原理讲起,不用复杂术语,而是用“浏览器和服务器的对话”类比,把“异步请求”的底层逻辑、核心步骤拆解得明明白白,让你真正理解AJAX不是“黑盒工具”,而是前端和后端通信的“底层规则”;接着用真实代码实例对比axios和fetch——从最基础的“发送GET请求”写法,到“拦截器”“自动转换JSON”“错误处理”这些关键功能差异,再到兼容性、体积大小等细节,全用具体场景帮你捋清楚;最后结合实际开发场景给出明确 如果需要复杂拦截、统一处理请求,选axios更高效;如果追求轻量、原生兼容,fetch更适合。

不管你是刚入门的新手想打牢基础,还是工作中常写请求的老鸟想梳理知识,看完这篇,AJAX原理和请求工具的选择问题,就能一次性搞懂。

你做前端开发时,有没有过这种崩溃时刻?写了个请求代码,要么页面卡着不动,要么拿到的数据是“乱码”,要么明明接口返回404,控制台却没报错——其实这些问题,大多和AJAX原理没搞懂,或者选了不适合的请求工具(axios/fetch)有关。今天我用自己踩过的坑、帮朋友解决过的问题,把这些知识点掰碎了讲,看完你再写请求代码,肯定比之前顺10倍。

浏览器和服务器的“悄悄话”:AJAX到底怎么工作?

很多人对AJAX的印象是“异步请求”,但其实它的本质是浏览器和服务器之间的“秘密对话”——不用刷新页面,就能偷偷传数据。我举个最接地气的例子:你去奶茶店点单,以前得站在柜台前等奶茶做好(同步),现在可以扫个码下单,然后找位置坐会儿(异步),奶茶做好了店员会喊你(响应)——AJAX就是这个“扫码下单+喊你取餐”的过程。

具体来说,AJAX的核心是XMLHttpRequest(XHR)——你可以把它当成一个“通讯员”,专门帮你和服务器传消息。它的工作流程就四步,我用“帮朋友查快递”的场景给你模拟一遍:

  • 创建通讯员var xhr = new XMLHttpRequest()——相当于你找了个跑腿的,专门帮你查快递。
  • 告诉通讯员要做什么xhr.open('GET', 'https://api.kuaidi100.com/query?id=12345')——你跟跑腿的说:“去查一下单号12345的快递,用GET方式问(就是‘获取信息’)。”
  • 让通讯员出发xhr.send()——跑腿的去快递站了。
  • 等通讯员带回消息xhr.onreadystatechange = function() { if(xhr.readyState === 4 && xhr.status === 200) { console.log(xhr.responseText) } }——跑腿的回来告诉你:“快递到小区门口了(readyState=4表示完成,status=200表示成功)”,你就能拿到快递信息(xhr.responseText)。
  • 是不是特好懂?我之前帮朋友做一个美食博客的“最新评论”功能,刚开始直接用同步请求,用户点“加载更多”时,页面卡着不动,像死机了一样——因为同步请求会“霸占”浏览器,直到服务器返回数据才能做别的。后来换成AJAX异步请求,用户点完按钮还能继续划页面,评论加载好了自动弹出来,体验瞬间好太多。

    但 AJAX 也不是完美的——它有个“同源策略”的限制,就是通讯员只能去和当前页面域名、端口、协议都一样的服务器传消息。比如你本地页面是http://localhost:3000,想调用https://api.taobao.com的接口,通讯员会直接拒绝(跨域错误)。这时候得让后端帮忙“开绿灯”(设置CORS,也就是Access-Control-Allow-Origin: *),或者用JSONP(但现在基本不用了)。我去年做一个电商项目时,就因为后端没开CORS,折腾了一下午才解决——所以记着,跨域问题不是前端的锅,得找后端同学帮忙。

    选axios还是fetch?用3个真实场景帮你做决定

    现在前端请求工具就俩主流:axios(第三方库)fetch(浏览器原生API)。我见过太多人纠结“选哪个”,其实根本不用死记硬背,用3个开发中最常遇到的场景,你自己就能做决定。

    场景1:发送简单GET请求——写法差在哪里?

    假设你要获取“今日天气”的数据,接口是https://api.weather.com/v1/current?city=beijing

    用axios的写法

    axios.get('https://api.weather.com/v1/current?city=beijing')
    

    .then(res => {

    console.log('天气数据:', res.data) // 直接拿到JSON数据

    })

    .catch(err => {

    console.log('请求失败:', err)

    })

    用fetch的写法

    fetch('https://api.weather.com/v1/current?city=beijing')
    

    .then(res => {

    if(!res.ok) { // 必须手动检查HTTP状态

    throw new Error('请求失败:' + res.status)

    }

    return res.json() // 必须手动转换JSON

    })

    .then(data => {

    console.log('天气数据:', data)

    })

    .catch(err => {

    console.log('错误:', err)

    })

    看出区别了吗?axios的链式调用更“省心”——不用手动检查状态,不用手动转JSON,直接拿res.data就行。而fetch得“多走两步”:先检查res.ok(不然404不会报错),再调用res.json()才能拿到数据。我之前帮同事看代码,他用fetch的时候忘了加res.json(),结果控制台打印出ReadableStream(可读流),折腾了半小时才反应过来——这就是没搞懂fetch的“脾气”。

    场景2:处理JSON数据——谁更省心?

    做登录功能时,你需要给后端传{ username: 'admin', password: '123456' }这样的JSON数据。

    用axios的写法

    axios.post('https://api.example.com/login', {
    

    username: 'admin',

    password: '123456'

    })

    .then(res => {

    console.log('登录结果:', res.data)

    })

    用fetch的写法

    fetch('https://api.example.com/login', {
    

    method: 'POST',

    headers: {

    'Content-Type': 'application/json' // 必须手动设置

    },

    body: JSON.stringify({ // 必须手动转成字符串

    username: 'admin',

    password: '123456'

    })

    })

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

    .then(data => {

    console.log('登录结果:', data)

    })

    axios有多贴心?它会自动帮你做3件事

  • 把请求数据转换成JSON字符串(不用写JSON.stringify);
  • 自动设置请求头Content-Type: application/json
  • 把响应数据自动转换成JSON对象(不用写res.json())。
  • 而fetch得你“亲手”做这3件事——我之前做登录功能时,用fetch忘了设置Content-Type,结果后端告诉我“没收到数据”,查了半天才发现是这个问题。后来换成axios,直接传对象就行,省了好多事儿。

    场景3:错误处理——踩过的坑告诉你答案

    假设你请求一个不存在的接口(比如https://api.example.com/nonexistent),会发生什么?

    axios的表现

    直接进入catch,错误信息里会明确写着Request failed with status code 404——你一眼就知道是“接口不存在”。

    fetch的表现

    不会进入catch!因为fetch的“错误定义”很严格:只有网络错误(比如断网、服务器宕机)才会reject,HTTP错误(比如404、500)不算“错误”。你得手动检查res.okres.oktrue表示状态码200-299,否则是false),然后自己抛出错误:

    fetch('https://api.example.com/nonexistent')
    

    .then(res => {

    if(!res.ok) {

    throw new Error(请求失败:${res.status}) // 手动抛错

    }

    return res.json()

    })

    .catch(err => {

    console.log(err) // 现在才会打印“请求失败:404”

    })

    我去年在做一个电商项目时,就踩过fetch的坑:用户点“提交订单”按钮,接口返回404,但页面没任何提示(因为没进入catch),用户以为没提交成功,反复点了好几次——后来换成axios,直接在catch里弹出“提交失败,请重试”,问题就解决了。

    一张表帮你快速对比核心差异

    为了让你更清楚,我把axios和fetch的核心差异做成了表格——直接看这张表,就能决定选哪个

    核心维度 axios fetch
    请求方法支持 支持所有常用方法(GET/POST等),写法简洁 支持所有方法,但需手动配置
    自动转换JSON 是(请求/响应都自动处理) 否(需手动调用JSON.stringify/res.json())
    错误处理 HTTP错误(404/500)会reject 仅网络错误会reject,HTTP错误需手动检查
    兼容性 支持IE11及以上(需引入库) 支持Chrome 42+/Firefox 39+,IE11需polyfill
    体积大小 约10KB(min版) 原生API,无需额外引入

    看到这儿,你应该有答案了吧?如果你的项目需要:

  • 频繁处理JSON数据;
  • 省心的错误处理;
  • 兼容IE11;
  • 少写冗余代码;
  • 选axios准没错。如果你的项目追求:

  • 轻量(不想引入第三方库);
  • 原生API(不想依赖外部工具);
  • 现代浏览器兼容性(不用管IE11);
  • fetch是更好的选择。

    其实我身边的前端同事,80%的项目都在用axios——不是说fetch不好,而是axios把开发中常遇到的“麻烦事”都帮你解决了,能省很多时间。比如拦截器功能(axios可以统一处理所有请求的token,不用每个请求都写一遍)、取消请求(比如用户快速点击按钮,可以取消之前的请求),这些都是fetch没有的“加分项”。

    你最近做项目用了axios还是fetch?有没有遇到什么奇怪的问题?欢迎评论区聊两句,我帮你参谋参谋—— 前端的坑,踩过才知道有多疼啊~


    本文常见问题(FAQ)

    AJAX名字里有XML,是不是一定要用XML传数据?

    其实不是哦,AJAX里的XML是“历史遗留”——早期AJAX主要用XML格式传数据,所以名字里带了XML。但现在前端开发几乎都用JSON传数据,AJAX的核心是“异步请求+不刷新页面”,跟用什么格式没关系。比如你现在用axios发请求,传的是JSON对象,本质还是AJAX的范畴。

    axios和fetch的错误处理到底不一样在哪?我总搞混

    最核心的区别是“HTTP错误算不算错”——比如请求一个不存在的接口(404),axios会直接进catch,告诉你“Request failed with status code 404”;但fetch不会,它觉得“我成功发了请求,只是服务器返回404”,所以得你手动检查res.ok(res.ok是true才表示200-299的成功状态),再自己抛错才能进catch。我之前用fetch的时候没检查res.ok,结果404了页面还没反应,查了半天才找到问题。

    项目要兼容IE11,选axios还是fetch啊?

    优先选axios!因为axios本身支持IE11,不用额外加代码;但fetch是现代浏览器的原生API,IE11不支持,得加polyfill(比如whatwg-fetch)才能用。如果你的项目要覆盖IE11用户,用axios会省很多兼容性的麻烦——我之前帮客户做官网,一开始用fetch,结果IE11下全报错,后来换成axios就好了。

    用fetch拿到ReadableStream是怎么回事?怎么解决?

    这是因为你没手动转JSON!fetch的响应结果默认是一个ReadableStream(可读流),得调用res.json()才能把它转换成JSON对象。比如你请求天气接口,用fetch的话,得先写.then(res => res.json()),再在后面的.then里处理数据。我同事之前写fetch代码忘了这一步,结果控制台打印出ReadableStream,还以为接口返回错了,折腾了半小时才搞明白——记住,fetch不会自动帮你转JSON,得自己动手。

    axios的拦截器有啥用?我怎么没感觉到它的好处?

    拦截器能帮你“统一处理所有请求/响应”,比如项目里所有请求都要带token,你不用每个请求都写一遍token,用axios的请求拦截器就能搞定:比如写一段axios.interceptors.request.use(config => { config.headers.Authorization = ‘Bearer ‘ + token; return config; }),这样所有请求都会自动加token。再比如响应拦截器,可以统一处理错误,比如所有401(未登录)的响应都跳转到登录页——这些功能fetch没有,得自己写逻辑,而axios帮你封装好了,能省超多重复代码。我现在做项目,不管大小都用axios的拦截器,真的能少写好多冗余代码。

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

    社交账号快速登录

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