如何使用JS Fetch处理Django Rest Framework API的400等非成功状态码
处理DRF API的400错误提示
嘿,这个情况我太熟悉啦!DRF返回的400错误里藏着非常有用的字段校验信息,咱们只需要调整一下fetch的处理逻辑,就能把这些信息展示给用户——毕竟fetch默认只有网络错误才会抛出异常,像400这类HTTP状态码错误会被当成“有效响应”直接进入then,所以得手动处理才行。
核心思路
先检查响应的response.ok属性(它只在状态码200-299之间时为true):
- 如果是成功状态(比如201 Created),正常解析JSON处理成功逻辑;
- 如果是错误状态(比如400),先解析错误响应里的JSON,再把这些错误信息整理成用户能看懂的提示。
完整代码示例
这里给你写个可直接用的版本,包含成功、400错误、网络错误的全流程处理:
// 假设yourFormData是你要提交的表单数据对象 const yourFormData = { email: 'test@example.com', password: '123' }; fetch('/api/your-endpoint/', { method: 'POST', headers: { 'Content-Type': 'application/json', // 如果你的API需要认证,记得加Authorization头 // 'Authorization': 'Token your-auth-token' }, body: JSON.stringify(yourFormData) }) .then(response => { // 先判断响应是否成功 if (response.ok) { return response.json(); } // 处理400这类错误:解析错误JSON后抛出,让catch统一处理 return response.json().then(errorData => { throw new Error(JSON.stringify(errorData)); }); }) .then(successData => { // 处理201创建成功的逻辑 console.log('数据创建成功:', successData); alert('操作成功!'); }) .catch(error => { // 这里会捕获网络错误,以及我们抛出的400错误信息 try { // 解析DRF返回的错误JSON const errorDetails = JSON.parse(error.message); // 整理错误信息:DRF的400错误通常是{字段名: [错误信息数组]}的结构 let errorMessage = '输入有误,请检查:\n'; // 处理非字段错误(比如全局校验的detail字段) if (errorDetails.detail) { errorMessage += errorDetails.detail + '\n'; } // 遍历所有字段的错误 for (const [field, messages] of Object.entries(errorDetails)) { if (field !== 'detail') { // 跳过已经处理过的detail errorMessage += `• ${field}: ${messages.join('、')}\n`; } } alert(errorMessage.trim()); } catch (parseError) { // 如果是网络错误之类的非JSON错误,直接显示原始信息 alert(`请求失败:${error.message}`); } });
简化版(无需抛出错误)
如果你不想用throw,也可以在第一个then里直接分支处理,代码更直观:
fetch('/api/your-endpoint/', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(yourFormData) }) .then(response => { if (response.ok) { // 处理成功 return response.json().then(data => { console.log('成功:', data); alert('数据创建完成!'); }); } else { // 处理400错误 return response.json().then(errorData => { let msg = '请修正以下输入问题:\n'; Object.values(errorData).forEach(messages => { msg += `- ${messages.join('、')}\n`; }); alert(msg.trim()); }); } }) .catch(networkError => { // 处理网络连接问题 alert(`网络出错啦:${networkError.message}`); });
小提示
DRF的400错误结构可能因你的序列化器配置略有不同:
- 字段错误:通常是
{"字段名": ["错误提示"]}; - 全局错误(比如权限、非字段校验):会有
detail字段,值为字符串或数组。
你可以根据自己的API返回结构调整错误信息的整理逻辑~
内容的提问来源于stack exchange,提问作者Loic Duros
相关产品推荐
相关产品推荐

