You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 04:36:13