React中Axios无法捕获GoLang API返回的非200 HTTP响应问题
问题分析与解决方案
你遇到的核心问题是:Go API返回非200状态码时,Axios没有进入catch块而是走到了then块,这通常是服务端响应处理错误或Axios配置异常导致的。
一、优先排查Go服务端的响应实现
Axios只会在服务器返回4xx/5xx状态码时触发catch,如果你的utils.FailureResp和utils.ERROR函数存在以下问题,会导致状态码被默认的200覆盖:
常见错误:先写响应体再设置状态码
Go的HTTP响应规则是:一旦开始向响应体写入内容,状态码会被自动设为200,后续再调用w.WriteHeader()不会生效。
错误示例:
// 错误:先写响应体,再设置状态码,最终状态码还是200 func FailureResp(w http.ResponseWriter, statusCode int, message string) { json.NewEncoder(w).Encode(map[string]string{"error": message}) w.WriteHeader(statusCode) // 这行代码无效 }
正确实现应该先设置状态码,再写入响应体:
func FailureResp(w http.ResponseWriter, statusCode int, message string) { w.WriteHeader(statusCode) // 必须先设置状态码 w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(map[string]string{"error": message}) } func ERROR(w http.ResponseWriter, statusCode int, err error) { w.WriteHeader(statusCode) w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(map[string]string{"error": err.Error()}) }
二、验证服务端实际返回的状态码
用curl或Postman直接调用API,确认返回的状态码是否符合预期:
curl -v YOUR_API_ENDPOINT
如果返回的状态码是200,说明服务端的响应实现确实有问题,回到第一步修正工具函数。
三、检查Axios的validateStatus配置
Axios默认只把2xx范围的状态码视为成功,其他状态码触发catch。如果你的项目全局修改了validateStatus配置,会导致非200状态码也进入then块。
检查全局配置
查看项目中是否有类似代码:
// 错误示例:所有状态码都视为成功 axios.defaults.validateStatus = (status) => status >= 200;
修复方式
要么恢复默认配置,要么在单个请求中显式指定validateStatus:
axios.get('YOUR_API_ENDPOINT', { validateStatus: (status) => status >= 200 && status < 300 // 仅2xx状态码走then }) .then(response => { console.log('Data:', response.data); }) .catch(error => { if (error.response) { console.log(error.response.data); console.log(error.response.status); console.log(error.response.headers); } else if (error.request) { console.log(error.request); } else { console.log('Error', error.message); } });
四、排查CORS配置问题
如果浏览器控制台有CORS相关错误,说明服务端没有正确处理跨域请求的非200响应。需要在Go服务端的CORS中间件中允许自定义响应头,并确保状态码被正确传递:
// 示例CORS中间件 func CORSMiddleware(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Access-Control-Allow-Origin", "*") w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS") w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization") if r.Method == "OPTIONS" { w.WriteHeader(http.StatusOK) return } next.ServeHTTP(w, r) }) }
内容的提问来源于stack exchange,提问作者Robin
相关产品推荐
相关产品推荐

