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

前端http状态码400返回值获取实例|axios与fetch实战代码解析及常见问题

前端http状态码400返回值获取实例|axios与fetch实战代码解析及常见问题 一

文章目录CloseOpen

用axios轻松搞定400返回值:从代码配置到实战避坑

我敢说,现在前端项目里十有八九在用axios发请求,它的拦截器功能简直是处理错误的神器。但你知道吗?大部分人配置axios时,只配了请求拦截器加token,却忽略了响应拦截器,这就是400返回值拿不到的关键原因。

基础配置:让axios主动“交出”400返回值

你平时写axios请求是不是这样:

axios.post('/api/login', { username, password })

.then(res => { / 成功处理 / })

.catch(err => { console.log('请求失败', err); });

如果后端返回400,err里其实藏着宝贝——err.response。我之前帮一个朋友看代码,他就是在catch里只打印err,结果控制台只有Error: Request failed with status code 400,根本看不到后端返回的{ "error": "密码格式错误,需包含大小写字母" }。后来我让他改了catch里的代码:

.catch(err => {

if (err.response && err.response.status === 400) {

console.log('后端说:', err.response.data); // 这下就拿到具体错误了!

}

});

他当时眼睛都亮了,说“原来400的返回值藏在response.data里啊!”其实axios的错误对象结构是有规律的,err.response里包含了状态码(status)、响应头(headers)和返回数据(data),只要你不直接丢掉err,就能挖出来。

进阶技巧:用拦截器统一处理,一次配置终身受益

如果你每个请求都写一遍err.response判断,代码会很冗余。我现在的项目里,都会配一个响应拦截器,统一处理400这类错误。比如这样:

// 创建axios实例时配置拦截器

const api = axios.create({ baseURL: '/api' });

api.interceptors.response.use(

response => response, // 成功时直接返回

error => {

// 处理错误状态码

if (error.response) {

const { status, data } = error.response;

if (status === 400) {

// 可以在这里统一提示错误,或者把data存起来

alert(请求错误:${data.error || '请检查参数格式'});

}

}

return Promise.reject(error); // 记得返回reject,让业务层能继续处理

}

);

我去年在做一个电商项目时,后端对所有400错误都返回{ "code": 1001, "msg": "具体错误信息" },我用这个拦截器后,所有页面的表单提交错误都能自动弹框提示具体原因,用户体验一下子上去了。当时产品经理还夸我:“你怎么做到让错误提示这么智能的?”其实就是拦截器的功劳。

避坑指南:这些“坑”我替你踩过了

就算配了拦截器,你可能还是会遇到“400返回值拿不到”的情况。我 了三个最常见的坑,你可以对照看看:

问题场景 现象 原因 解决办法
跨域请求时400 控制台只显示400,response是undefined 跨域配置问题,服务器没返回Access-Control-Expose-Headers 让后端在响应头加Access-Control-Expose-Headers:
网络错误和400混淆 有时err.response是undefined 网络断开或服务器没响应时,没有response对象 先判断if (error.response)再处理状态码
data是字符串不是对象 打印data显示"{"error":"参数错误"}" 后端返回的Content-Type不是application/json JSON.parse(data)手动解析,或让后端改响应头

比如跨域那个坑,我之前帮一个外包项目调试时遇到过。前端用axios请求另一个域名的接口,后端返回400,但error.response一直是undefined。后来查文档才发现,跨域请求时,浏览器会限制前端能访问的响应头,默认只能拿到Cache-Control、Content-Length等基本头,状态码虽然能看到,但response.data会被隐藏。解决办法很简单,让后端在nginx或接口代码里加一句Access-Control-Expose-Headers: ,允许暴露所有响应头,前端就能拿到完整的response了。

fetch处理400状态码:别让“不报错”的特性坑了你

说完axios,再聊聊fetch。现在很多新项目用fetch原生API,轻量又不用引依赖,但它处理400状态码的逻辑和axios不一样,这也是很多人踩坑的地方。

你可能不知道:fetch默认不把400当成“错误”

前阵子带实习生小李做项目,他用fetch发请求,遇到400时控制台没报错,代码直接走到了then里,结果他以为请求成功了,一直纳闷“为什么数据是空的?”其实这是fetch的设计特性——只有网络错误(比如断网)或请求被阻止(比如CORS失败)时,fetch才会reject;像400、500这类HTTP错误状态码,它会认为“请求成功发出去并收到了响应”,所以会resolve

所以用fetch处理400,第一步就是手动判断状态码。正确的写法应该是这样:

fetch('/api/user', { 

method: 'POST',

body: JSON.stringify({ age: 'abc' }) // 故意传错参数,触发400

})

.then(response => {

// 先判断response.ok,它在status为200-299时才是true

if (!response.ok) {

// 400时会走到这里,需要把响应体转成json再抛出

return response.json().then(err => Promise.reject(err));

}

return response.json(); // 成功时正常解析

})

.then(data => console.log('成功数据:', data))

.catch(error => {

console.log('400错误信息:', error); // 这里就能拿到后端返回的错误数据了

});

小李后来跟我说:“原来fetch的then里藏着400啊!我之前直接response.json(),结果拿到个空对象,还以为后端没返回东西。”其实是他没先判断response.ok,直接解析了“错误的响应体”,自然拿不到数据。

实战对比:axios和fetch处理400的核心差异

为了让你更清楚两者的区别,我做了个对比表,你可以保存下来:

对比项 axios fetch
400是否触发catch 是(主动reject) 否(需手动判断response.ok后reject)
返回值获取方式 err.response.data 需先response.json()再获取
错误拦截 支持拦截器统一处理 需手动在then里判断
兼容性 IE不支持(需polyfill) 现代浏览器支持,IE完全不支持

我个人在项目里,如果是中小型应用,会优先用axios,拦截器太香了;如果是追求极致轻量、不需要兼容旧浏览器的场景,才会用fetch,但一定会记得加response.ok判断。

权威验证:MDN文档早就说清楚了

可能你会说“你怎么确定fetch就是这样的?”其实MDN的fetch文档里明确写着:“A fetch() promise rejects only when a network error occurs, although this usually means permissions issues or similar. A fetch() promise does not reject on HTTP errors (404, etc.). Instead, a then() handler must check the Response.ok and/or Response.status properties.”(fetch的promise只在网络错误时reject,HTTP错误需要通过Response.ok或status判断)。你可以去MDN fetch文档看看(链接已加nofollow),官方说明最靠谱。

不管你用axios还是fetch,处理400状态码的核心就是“别放过响应体里的错误信息”。服务器返回400时,十有八九会在data里告诉你“参数a格式错误”“缺少必填字段b”,这些信息比单纯的“400 Bad Request”有用100倍。我自己的习惯是,拿到400返回值后,会先打印到控制台,再根据错误类型决定是给用户弹框提示,还是记录到日志系统里。

你平时处理400状态码时,有没有遇到过什么奇葩问题?比如后端返回的400没有data,或者返回的是HTML格式的错误页?如果按今天说的方法试了,欢迎回来告诉我效果,咱们一起把前端错误处理变得更顺畅!


其实啊,fetch和axios处理400返回值的差别,我刚接触fetch的时候也踩过坑。那会儿带的实习生小张,用fetch调登录接口,明明后端返回400说“密码格式不对”,他却跟我说“接口没报错啊,then里能走到,就是data是空的”。我一看他代码,好家伙,直接fetch().then(response => response.json()).then(data => { ... }),完全没管response的状态码——这就是fetch最坑的地方,它默认不把400当成“错误”。

你想啊,axios多省心,只要后端返回400,它直接就给你reject到catch里,你在catch里一掏err.response.data,错误信息就出来了。但fetch不一样,它觉得“只要服务器给我回了东西,不管200还是400,都是‘成功响应’”,所以会resolve到then里。这时候你要是不先判断response.ok(这玩意儿只有状态码200-299才是true),直接response.json(),拿到的可能就是个空对象,或者后端返回的错误字符串,根本没法用。后来我让小张在then里加了句if (!response.ok) { return response.json().then(err => Promise.reject(err)) },他才终于拿到了“密码格式不对”的具体提示,当时还拍大腿说“原来fetch的错误藏在这儿啊!”

至于怎么选,得看你项目情况。我自己做中小项目的时候,基本都用axios,它那个响应拦截器太香了——配一次就能全局处理所有400错误,不用每个请求都写一遍判断,省事儿。但如果是写个小工具,或者项目特别追求轻量,不想引axios这个依赖,那就用fetch,不过记着把判断response.ok的逻辑封装成个小函数,比如我现在写fetch请求,都会先调一下checkResponse(response),里面自动处理400、500这些状态码,返回解析好的data或者reject错误,用起来也顺手。


什么是HTTP 400状态码?为什么前端需要特别处理它的返回值?

HTTP 400状态码表示“请求错误”,通常是因为前端发送的请求参数格式不对、缺少必填字段或数据类型错误等。前端需要处理其返回值,是因为后端通常会在400响应中包含具体错误原因(比如“手机号格式错误”“密码长度不足”),正确获取这些信息能让用户知道哪里操作有误,避免盲目重试,提升体验。

使用axios时,为什么有时catch里拿不到400状态码的返回值?

最常见原因是没有正确访问错误对象的结构。axios中,400状态码的返回值藏在err.response.data里,如果你只打印err而没访问err.response,就只能看到错误提示文字。 如果没配置响应拦截器,或拦截器中直接return Promise.reject(error)却没保留error.response,也会导致返回值丢失。 在catch中先判断err.response?.status === 400,再通过err.response.data获取具体信息。

fetch和axios处理400返回值的主要区别是什么?该如何选择?

核心区别有两点:一是错误触发机制,axios会主动将400状态码的请求reject到catch中,而fetch默认不会(需手动判断response.ok后reject);二是返回值获取,axios直接通过err.response.data获取,fetch需先调用response.json()解析。选择上,中小项目推荐axios(拦截器能统一处理错误,更省心);追求轻量、不需要兼容旧浏览器的场景可用fetch,但要记得手动判断状态码。

跨域请求时,400状态码的返回值会被浏览器隐藏吗?如何解决?

会!跨域时如果后端没正确配置CORS响应头,浏览器可能会隐藏400的返回值。这是因为浏览器的同源策略限制,默认只暴露部分响应头(如Cache-Control)。解决办法是让后端在响应头中添加Access-Control-Expose-Headers: *(或具体需要的头字段),允许浏览器暴露响应体数据;同时前端确保在请求中不遗漏withCredentials: true(如果需要携带cookie)。

后端返回400时,前端应该如何向用户展示错误信息?有哪些最佳实践?

最佳实践是“具体、友好、不技术化”。比如后端返回{ "error": "密码需包含大小写字母和数字" },前端不要直接显示“error: 密码需包含…”,而是提炼为“请检查密码格式:需包含大小写字母和数字哦~”。 可根据错误类型分类展示:表单页直接在对应输入框下方显示红色提示文字;弹窗类请求用toast轻提示;复杂错误可提供“查看详情”按钮展开完整信息。避免用技术术语(如“400 Bad Request”),让用户一眼知道哪里错了、怎么改。

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

社交账号快速登录

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