为何Fetch API的.then函数即便response.ok为false时仍会执行
Fetch API 500状态码仍触发后续.then问题的原因与修复方案
核心原因
- Fetch API的设计规则为:仅当网络请求本身发生故障(如无网络、跨域被拦截、请求地址非法等)时,返回的Promise才会变为rejected状态进入
.catch()回调。只要服务器成功返回了HTTP响应,无论状态码是2xx、4xx还是5xx,都会进入.then()流程。 - 你当前代码的第一个
.then()回调中,所有分支要么有显式返回值,要么无显式返回(默认返回undefined),只要上一个Promise回调正常执行未抛出错误,就会自动触发链式调用的下一个.then(),因此第二个.then()无论接口返回什么状态码都会执行。 - 额外提示:你示例代码中第二个
.then()里的console.log(Data)存在变量名大小写笔误,参数为data但使用了大写的Data,实际运行会触发引用错误,需要修正。
修复方案
方案1:主动抛出错误终止正常.then流程
在非200状态码的分支处理完对应逻辑后主动抛出错误,让后续错误进入.catch()统一处理,仅状态码200时才会进入第二个.then():
fetch(testUrl, { headers, method: "POST" }) .then(response => { if (response.status === 200) { return response.json() } if (response.status === 401) { Logout() throw new Error('UNAUTHORIZED') } if (response.status === 500) { setTestApiFetchError({ 'error_type': "SERVER_ERROR", "error": true }) throw new Error('SERVER_ERROR') } throw new Error(`UNEXPECTED_STATUS: ${response.status}`) }) .then(data => { // 仅状态码200时会执行该回调 console.log(data) }) .catch(err => { // 统一处理所有错误场景 console.error('请求出错:', err.message) })
方案2:使用async/await语法优化逻辑可读性
改用async/await写法可以避免链式回调的嵌套问题,逻辑更清晰:
async function requestTestApi() { try { const response = await fetch(testUrl, { headers, method: "POST" }) if (response.status === 200) { const data = await response.json() console.log(data) return } if (response.status === 401) { Logout() return } if (response.status === 500) { setTestApiFetchError({ 'error_type': "SERVER_ERROR", "error": true }) return } // 其他状态码处理逻辑 console.error(`未处理的响应状态码:${response.status}`) } catch (err) { // 处理网络层面的请求错误 console.error('网络请求失败:', err) } }
内容的提问来源于stack exchange,提问作者Freduah Gideon
相关产品推荐
相关产品推荐

