React Native中Fetch API请求无成功/错误回调问题求助
问题分析与解决方案
核心原因
你遇到的问题根源在于带Authorization头的请求触发了React Native的预检OPTIONS请求,而你的Spring Boot后端禁用了CORS,直接拦截了OPTIONS请求,导致主请求处于挂起状态,Fetch的Promise既不resolve也不reject,所以then和catch都不会执行。
移除Authorization头后,请求属于简单请求,不会触发预检,后端拒绝请求后直接进入catch,这也验证了预检请求是问题的关键。而Postman不会自动发送预检OPTIONS请求,所以能直接得到401响应。
解决方案
1. 后端Spring Boot配置CORS支持
必须让后端允许预检OPTIONS请求,同时放行Authorization头。可以通过以下两种方式配置:
方式一:添加全局CORS配置类
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import org.springframework.web.filter.CorsFilter; @Configuration public class CorsConfig { @Bean public CorsFilter corsFilter() { UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); CorsConfiguration config = new CorsConfiguration(); // 允许前端域名(开发环境可临时设为*,生产环境替换为实际域名) config.addAllowedOrigin("*"); // 允许所有请求方法 config.addAllowedMethod("*"); // 允许Authorization等自定义请求头 config.addAllowedHeader("*"); // 允许携带凭证(如果业务需要) config.setAllowCredentials(true); // 预检请求缓存时长,减少重复OPTIONS请求 config.setMaxAge(3600L); source.registerCorsConfiguration("/**", config); return new CorsFilter(source); } }
方式二:在Controller或方法上添加@CrossOrigin注解
import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RestController; @RestController @CrossOrigin(origins = "*", allowedHeaders = "*", methods = "*") public class LoginController { @PostMapping("/login") public String login() { // 你的登录业务逻辑 return "login response"; } }
2. 前端Fetch代码优化
即使后端修复了CORS,Fetch默认不会把HTTP错误码(比如401)视为Promise异常,需要在then中手动判断并抛出错误,才能进入catch逻辑:
export function login(username, password) { const url = `${baseUrl}/login`; const usernamePassword = `${username}:${password}`; const encodedString = Buffer.from(usernamePassword).toString('base64'); console.log('encoded : ', encodedString); return fetch(url, { headers: { 'Authorization': `Basic ${encodedString}`, 'Cache-Control': 'no-cache' } }).then(resp => { console.log(resp); // 手动判断HTTP状态码,非2xx范围则抛出错误 if (!resp.ok) { throw new Error(`请求失败!状态码: ${resp.status}`); } return resp.json(); // 根据业务需求处理响应体 }).catch(err => { console.log(err); throw err; // 向上抛出错误,方便上层逻辑处理 }); }
验证步骤
- 重启Spring Boot服务,确保CORS配置生效;
- 重新调用login方法,查看控制台是否输出响应信息;
- 如果问题仍存在,可使用Charles或Fiddler抓包,确认OPTIONS请求是否被正常响应。
内容的提问来源于stack exchange,提问作者amit gupta
相关产品推荐
相关产品推荐

