

统一声明:
1.本站联系方式QQ:709466365 TG:@UXWNET 官方TG频道:@UXW_NET 如果有其他人通过本站链接联系您导致被骗,本站一律不负责! 2.需要付费搭建请联系站长QQ:709466365 TG:@UXWNET 3.免实名域名注册购买- 游侠云域名 4.免实名国外服务器购买- 游侠网云服务
这篇文章不搞抽象对比,而是把两者的核心区别拆成开发中用得到的具体场景:比如老项目要兼容IE,Ajax还是刚需;新项目用ES6+,Fetch的链式调用更清爽;甚至连“跨域凭证怎么带”“响应体怎么读”这些容易踩雷的细节,都帮你理得明明白白。搞懂这几点,下次写请求逻辑不用再翻文档查资料,直接选对工具、避开坑,开发效率蹭蹭涨。
你有没有过这种情况?做前端项目调接口时,纠结到底用Ajax还是Fetch——明明都是发请求,前者要写一堆啰嗦的配置,后者看起来简洁却偶尔“耍脾气”,比如404了不进catch,害得你翻半小时代码才找到问题?我前两年做项目时也总踩这种坑,后来把两者的差异拆成“开发里用得到的具体场景”,现在写请求逻辑再也没犯过难。今天就把这些经验分享给你,不用记抽象概念,跟着场景走就能选对工具。
从用法细节看差异:为什么Fetch写起来更爽但偶尔坑人?
先说说用法复杂度——你肯定记得Ajax的“标准流程”:先创建XMLHttpRequest对象,然后open方法设置请求方式和地址,onreadystatechange监听状态变化,还要判断readyState === 4(请求完成)和status === 200(成功),最后JSON.parse(responseText)拿数据。比如我刚学前端时写过这样的代码:
const xhr = new XMLHttpRequest();
xhr.open('GET', '/api/data', true);
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === 200) {
const data = JSON.parse(xhr.responseText);
console.log(data);
}
};
xhr.send();
当时觉得“怎么这么麻烦”,后来用Fetch才发现——原来请求可以写得这么简洁:
fetch('/api/data')
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error(error));
但别急着高兴,Fetch的“坑”藏在细节里:比如response.json()
本身是个Promise,你得再套一层.then
才能拿到数据。我第一次用Fetch时,忘了这一步,结果console.log
出来的是个Response对象,不是数据,查了半小时才反应过来——哦,原来得“拆两层”。
再比如JSON解析:Ajax得手动调用JSON.parse(xhr.responseText)
,如果后端返回的不是JSON格式,还得处理报错;而Fetch用response.json()
会自动解析,但如果响应体是空的,或者格式不对,这个方法会reject。我之前做一个导出接口,后端返回二进制流,我误用了response.json()
,结果直接进了catch,后来换成response.blob()
才解决。
兼容性与错误处理:哪些场景必须选Ajax?
再讲兼容性——这是Ajax至今还没被完全取代的核心原因。比如去年我帮一个老项目做维护,客户明确要求兼容IE11,我一开始图省事用了Fetch,结果测试时页面全崩了——原来IE11根本不支持Fetch API(MDN文档明确提到这一点,链接:MDN Fetch API)。后来没办法,只能把Fetch改成Ajax,才解决了兼容性问题。如果你做的是需要兼容旧浏览器(比如IE11及以下)的项目,Ajax还是刚需;如果是现代项目(比如只支持Chrome、Edge、Firefox最新版),Fetch更推荐。
然后是错误处理——这是两者最容易踩坑的区别。Ajax的错误分两类:网络错误(比如断网)用xhr.onerror
处理,HTTP错误(比如404、500)要在onreadystatechange
里判断xhr.status
;而Fetch不一样——只有网络错误(比如断网、跨域被拦截)会让Promise reject,HTTP错误(比如404、401)不会,反而会resolve,因为Fetch认为“服务器已经返回了响应”。比如我之前做登录接口,后端返回401 Unauthorized(用户未授权),我用Fetch写的代码是这样的:
fetch('/api/login', { method: 'POST', body: JSON.stringify(loginData) })
.then(response => response.json())
.then(data => {
// 处理登录成功逻辑
})
.catch(error => {
console.error(error);
});
结果测试时,输入错误密码,页面没反应——因为401是HTTP错误,Fetch没有reject,反而进入了第一个.then
,但response.json()
解析的是错误信息(比如{ message: 'Unauthorized' }
),而我没检查response.ok
,导致成功逻辑没执行,错误也没捕获。后来查了Chrome开发者文档(链接:Chrome Fetch 指南)才知道,得手动检查response.ok
:
fetch('/api/login', { method: 'POST', body: JSON.stringify(loginData) })
.then(response => {
if (!response.ok) {
throw new Error('请求失败:' + response.status);
}
return response.json();
})
.then(data => {
// 处理登录成功逻辑
})
.catch(error => {
console.error(error); // 现在401会进这里
});
加了这行if (!response.ok)
,才终于把HTTP错误捕获到了。
最后再给你一张核心差异对比表,帮你快速理清两者的区别:
对比项 | Ajax | Fetch |
---|---|---|
用法复杂度 | 需要手动配置XHR对象、监听状态,代码较啰嗦 | 基于Promise,链式调用更简洁,无需手动监听状态 |
JSON解析 | 需手动调用JSON.parse(xhr.responseText) | 用response.json()自动解析(返回Promise) |
兼容性 | 支持所有现代浏览器及IE5+ | 不支持IE11及以下,需polyfill |
错误处理 | 网络错误用onerror,HTTP错误需判断xhr.status | 仅网络错误reject,HTTP错误需手动检查response.ok |
Promise支持 | 不原生支持,需手动封装 | 原生支持Promise,写法更流畅 |
如果你按这些方法试了,比如用Fetch时加了response.ok
检查,或者兼容旧项目用了Ajax,欢迎回来告诉我效果!要是遇到其他坑,也可以在评论区留言,我们一起避坑~
Fetch写起来简洁,为什么偶尔会踩坑?
Fetch的坑主要藏在细节里,比如它的response.json()本身是个Promise,得再套一层.then才能拿到数据,我第一次用的时候忘了这步,结果console.log出来的是Response对象不是数据。还有JSON解析的问题,如果响应体是空的或者格式不对,response.json()会直接reject,比如我之前做导出接口用了这个方法,结果进了catch,后来换成response.blob()才解决。
另外Fetch的错误处理也容易踩坑,只有网络错误(比如断网)会让Promise reject,像404、500这种HTTP错误不会,反而会resolve,得手动检查response.ok才行,我之前做登录接口没加这步,输入错误密码页面没反应,查了半天才发现问题。
老项目要兼容IE11,选Ajax还是Fetch?
肯定选Ajax,因为IE11根本不支持Fetch API(MDN文档都明确说了)。我去年帮一个老项目维护,一开始图省事用了Fetch,结果测试时页面全崩了,后来换成Ajax才解决兼容性问题。如果是需要兼容旧浏览器(比如IE11及以下)的项目,Ajax还是刚需,现代项目只用最新浏览器的话可以优先选Fetch。
Ajax和Fetch处理JSON数据有什么不一样?
Ajax得手动调用JSON.parse(xhr.responseText)来解析JSON数据,如果后端返回的不是JSON格式,还得自己处理报错;而Fetch用response.json()会自动解析,但这个方法返回的是Promise,得再用.then才能拿到数据,我第一次用的时候没注意,结果没拿到想要的内容。
还有如果响应体是空的或者格式不对,Fetch的response.json()会reject,比如我之前做接口调试,后端返回了HTML,用这个方法直接进了catch,后来换成response.text()才拿到内容;而Ajax的JSON.parse遇到无效JSON会抛出错误,得自己加try catch处理。
为什么Fetch遇到404不会进catch?
因为Fetch的错误处理逻辑和Ajax不一样,它只把网络错误(比如断网、跨域被拦截)当成“错误”让Promise reject,而像404、401这种HTTP错误,Fetch认为“服务器已经返回了响应”,所以会resolve。我之前做项目的时候,输错接口地址导致404,结果Fetch没进catch反而进了then,查了Chrome文档才知道,得手动检查response.ok,如果!response.ok就throw一个错误,这样才能让Promise reject进catch处理。
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!
7. 如遇到加密压缩包,请使用WINRAR解压,如遇到无法解压的请联系管理员!
8. 精力有限,不少源码未能详细测试(解密),不能分辨部分源码是病毒还是误报,所以没有进行任何修改,大家使用前请进行甄别!
站长QQ:709466365 站长邮箱:709466365@qq.com