React JS如何通过Fetch实现用户登录认证?
React + Fetch 实现正确的登录认证跳转逻辑
嘿,我看了你的代码,问题其实很明显——你现在不管登录请求成功与否,都会直接跳转到着陆页,而且你的fetchData方法还在使用硬编码的用户名密码,根本没用到输入框里的用户输入!下面我一步步帮你修改代码,实现仅当认证成功时才跳转的功能。
核心问题梳理
onSubmit方法直接跳转:你在调用fetchData()后立刻执行了this.props.history.push('/landing'),完全没等登录请求返回结果,所以不管凭证对错都会跳转。- 硬编码的请求参数:
fetchData里的请求体用的是固定的username: 'myUserName',没有绑定输入框的state值。 - 多余的请求参数:请求体里加了
Authorization字段,但这时候你还没拿到token,属于无效参数。
修改步骤及完整代码
第一步:修复fetchData方法,绑定用户输入并处理认证结果
我们要把请求参数换成state里的用户名和密码,同时在请求返回后判断是否认证成功,只有成功才跳转,失败则提示错误。
第二步:调整onSubmit方法,移除直接跳转逻辑
让onSubmit只负责触发登录请求,跳转逻辑交给fetch的成功回调处理。
完整修改后的代码
import React, { Component } from 'react'; import './Login.css'; import { withRouter } from 'react-router-dom'; class Login extends Component { constructor() { super(); this.state = { data: [], username: "", password: "", token: "", }; } componentDidMount() { // 登录是用户主动操作,页面加载时不需要发起请求,注释掉原调用 // this.fetchData(); } fetchData = () => { // 从state中获取用户输入的用户名和密码 const { username, password } = this.state; fetch('http://theapi/api/auth', { method: 'POST', headers: { 'Content-type': 'application/json', }, // 传递用户输入的凭证,移除多余的Authorization参数 body: JSON.stringify({ username: username, password: password }) }) .then(results => { // 先检查HTTP状态码,2xx以外的状态码都视为认证失败 if (!results.ok) { throw new Error('用户名或密码错误,请重试'); } return results.json(); }) .then(data => { // 认证成功:保存token,清空输入框,跳转至着陆页 this.setState({ data: data, token: data.token, username: "", password: "" }); this.props.history.push('/landing'); }) .catch(error => { // 处理错误:提示用户,打印错误日志 alert(error.message); console.error('登录失败:', error); }); } change = (e) => { this.setState({ [e.target.name]: e.target.value }); }; onSubmit = (e) =>{ e.preventDefault(); // 阻止表单默认提交行为 this.fetchData(); // 发起登录请求,跳转逻辑在fetch回调中处理 }; render() { console.log(this.state.data); return ( <div> <div className="loginContainer"> <h2>Member Login</h2> <form> <input id="username" name="username" placeholder="User Name" value={this.state.username} onChange={e => this.change(e) } className="form-control" /> <br /> <input id="password" name="password" type="password" placeholder="Password" value={this.state.password} onChange={e => this.change(e) } className="form-control" /> <br /> <button onClick={e => this.onSubmit(e)} className="btn btn-primary">Submit</button> </form> </div> </div> ); } } export default withRouter(Login);
额外说明
- 我注释掉了
componentDidMount里的this.fetchData(),因为登录应该是用户点击提交后才发起的,页面加载时不需要自动请求。 - 在
fetch的第一个then中,通过!results.ok判断HTTP状态码,即使返回JSON,只要状态码是401(未授权)或其他错误码,都会抛出错误进入catch分支。 - 错误提示用了
alert,你可以换成更友好的UI组件(比如在页面上显示错误文本)来提升用户体验。 - 假设你的API返回的
data中包含token字段,如果实际返回的字段名不同,记得修改data.token为对应的字段。
内容的提问来源于stack exchange,提问作者user1724708
相关产品推荐
相关产品推荐

