React中无法console.log打印DRF返回的400接口错误信息
问题根因
fetch API 仅在网络层面请求失败(断网、跨域拦截、DNS解析失败等场景)时才会触发catch回调,HTTP 协议层面的错误状态码(包括400、403、500等4xx/5xx响应)默认会被判定为请求成功,不会进入catch分支,因此原有代码无法捕获DRF返回的400错误内容。
修复方法
- 拿到响应对象后,先通过
res.ok属性判断响应状态:该属性仅在HTTP状态码处于200-299区间时返回true - 提前解析响应体的JSON内容,非2xx状态下手动抛出携带错误内容的异常,即可在
catch分支拿到后端返回的结构化错误信息
修复后的完整代码:
const onSubmit = (data) => { const user = { username: data.username, email: data.email, password: data.password, profile: { city: data.city, country: data.country, } }; fetch('http://127.0.0.1:8000/api/register', { method: 'POST', headers: { 'Content-Type':'application/json' }, body: JSON.stringify(user) }) .then(async res => { // 统一解析响应JSON,成功/失败响应都需要提取内容 const responseData = await res.json(); if (res.ok) { return responseData; } // 非2xx状态手动抛错,把后端返回的错误信息传递到catch分支 return Promise.reject(responseData); }) .then((data) => { // 此处处理注册成功的业务逻辑 console.log('注册成功', data); }) .catch((err)=>{ // 此处可拿到DRF返回的错误,例如 {"username":["A user with that username already exists."]} console.log('接口错误信息', err); }) };
注意不要直接在状态校验失败时抛出
res.json(),该方法返回的是Promise对象,直接抛出无法拿到解析后的错误内容,必须加await等待解析完成后再做后续处理。
如果习惯async/await语法,代码可读性会更高,参考写法:
const onSubmit = async (data) => { const user = { username: data.username, email: data.email, password: data.password, profile: { city: data.city, country: data.country, } }; try { const res = await fetch('http://127.0.0.1:8000/api/register', { method: 'POST', headers: { 'Content-Type':'application/json' }, body: JSON.stringify(user) }); const responseData = await res.json(); if (!res.ok) { console.log('注册错误:', responseData); return; } // 注册成功逻辑 console.log('注册成功', responseData); } catch (err) { // 此处捕获网络层面的请求异常 console.log('请求异常', err); } };
内容的提问来源于stack exchange,提问作者Emm
相关产品推荐
相关产品推荐

