React fetch请求登录接口报401及Unexpected end of input错误排查
React登录接口401及JSON解析报错解决方案
报错信息
- 接口请求返回
401 Unauthorized未授权状态 - 控制台抛出未捕获Promise异常:
SyntaxError: Unexpected end of input - 异常触发位置为登录逻辑中
result = await result.json()代码行
问题根因
- 错误配置
mode: 'no-cors':fetch的no-cors模式返回的是opaque不透明响应,前端JS无权读取响应体内容,调用.json()解析不可读/空响应体直接触发语法错误。这个模式仅适用于埋点上报这类不需要读取响应的场景,完全不适合登录这类需要拿接口返回值的业务。 - no-cors模式下自定义请求头不生效:你设置的
Content-Type: application/json属于CORS非简单请求头,no-cors模式下会被浏览器自动剔除,后端收到的请求不是JSON格式,参数解析失败直接返回401。 - 路由跳转写法错误:React Router v6版本不存在
Navigate.push的调用方式,需要通过useNavigate钩子生成跳转方法。 - 缺少响应状态校验和异常捕获:接口返回401等错误状态时,响应体可能不是合法JSON格式,直接调用
.json()必然报错。
修复方案
- 删除fetch配置中的
mode: 'no-cors'项,使用默认cors模式,同时协调后端为登录接口配置CORS响应头,允许前端所在域名跨域访问。 - 增加响应状态判断,只有状态码为2xx的成功响应才执行JSON解析,401状态单独做用户名密码错误提示。
- 修正路由跳转逻辑,使用
useNavigate钩子实现路由跳转。 - 增加try/catch异常捕获,避免未处理的Promise异常。
修正后代码
import { useEffect, useState } from 'react'; import { useNavigate } from 'react-router-dom'; function Login() { const [Username, setUsername] = useState(''); const [Password, setPassword] = useState(''); const navigate = useNavigate(); useEffect(() => { if (localStorage.getItem('user-info')) { navigate('/nxt'); } }, [navigate]); async function login() { try { const reqParams = { Username, Password }; const res = await fetch('http://api.kyc365pro.com:6061/login', { method: 'POST', headers: { 'Content-Type': 'application/json', Accept: 'application/json', }, body: JSON.stringify(reqParams), }); // 处理异常状态 if (!res.ok) { if (res.status === 401) { alert('用户名或密码错误'); return; } throw new Error(`请求失败,状态码:${res.status}`); } const result = await res.json(); localStorage.setItem('user-info', JSON.stringify(result)); navigate('/nxt'); } catch (err) { console.error('登录异常:', err); alert('登录失败,请检查网络后重试'); } } return ( <div> <h1>Login page</h1> <label>Username</label> <input type='text' placeholder='Username' onChange={(e) => setUsername(e.target.value)} /> <br /> <label>Password</label> <input type='password' placeholder='Password' onChange={(e) => setPassword(e.target.value)} /> <br /> <button onClick={login}>Login</button> </div> ); } export default Login
提示:如果修改后控制台报跨域错误,不要切回no-cors模式,必须由后端配置CORS规则解决,no-cors模式无法读取响应内容,不可能满足登录业务需求。
内容的提问来源于stack exchange,提问作者Nithish_Nth
相关产品推荐
相关产品推荐

