项目采用前后端分离进行设计,实现token登录验证
该示例只展示React Login Model 设计思路
前端:React 18 , Router V6; 后端(服务端) Springboot 2.4.5
React版本(可从package.json中查看)
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.12.1",
目的:
对项目进行登录访问控制,即未进行登录的用户不可访问登录可见页面。
未登录时,页面会自动跳转到登录页面,进行登录。
我们需要:
- 通过【路由】方式访问,需要从路由角度进行访问控制
- 创建 Login 组件,结合路由控制,来判断是否登录 : 1 未登录实现自动跳转到登录页面 2 登录后可跳转到访问页面
从实现一个简单的表单请求开始
简单页面展示效果
(注:这里无用户注册步骤,只有输入用户名密码后进行登录的功能)
登录验证通常会使用表单发送请求的方式
参考展示示例,如下为简单的html表单请求代码,通过点击button组件,上传输入的数据
<form method="post" action="/post">
<label for="name">User name</label>
<input id="name" name="name" />
<label for="password">Password</label>
<input id="password" name="password" />
<button>Login</button>
</form>
鉴于以上方式会刷新浏览器,并经历时代发展已被新方法Ajax
替代,改用JavaScript编写代码提交请求
const form = document.querySelector('form');
form.addEventListener('submit', handleSubmit);
function handleSubmit(event) {
const form = event.currentTarget;
fetch(form.action, {
method: form.method,
body: new FormData(form)
});
event.preventDefault();
}
- 通过获取表单元素,监听submit事件,点击提交按钮使用
fetch()
发送接口请求,实现服务端的数据发送。 event.preventDefault()
可以阻止浏览器的刷新,这就是典型的异步请求,可以使浏览器在不刷新的情况下,完成交互。
更进一步:Fetch API的使用
倘若我们快速点击Login按钮,代码中未设置阻止请求方法,从而会产生大量接口请求,导致服务器过载。
我们需要新的解决方法----在发送请求时,中止上一次请求。而Fetch
恰好可以做到。
Fetch
是下一代Ajax
技术,通过Promise方式来处理数据,具有更简洁明了的API.
从MDN Web Docs 社区 使用Fetch的wiki 可以了解到:
- Fetch API 提供了一个JavaScript接口,用于访问和操纵 HTTP 管道的一些具体部分,例如请求和响应。
- 它还提供了一个全局 fetch() 方法,该方法提供了一种简单,合理的方式来跨网络异步获取资源。
一个基本的 fetch 请求设置如下:
fetch(URL)
.then(response => response.json())
.then(data => console.log(data));
- Fetch函数通过网络(URL)获取所需数据(返回值可以是Json,HashMap等,方法中展示的是获取JSON文件), 并将其(data)打印到控制台。
- 代码中'response'只是一个 HTTP 响应,而不是真的
JSON
。为了获取JSON
的内容,我们需要使用response.json() 方法(该方法返回一个将响应 body 解析成JSON格式的Promise
对象),再通过.then()函数,获取Pormise
对象中的JSON对象
接下来我们可以更近一步,参考fetch()
,上传Json、上传多文件、发送带凭证等请求。以下为示例
//Example POST method implementation:
async function postData(url = '', data = {}) {
// Default options are marked with *
const response = await fetch(url, {
method: 'POST', // *GET, POST, PUT, DELETE, etc.
mode: 'cors', // no-cors, *cors, same-origin
cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
credentials: 'same-origin', // include, *same-origin, omit
headers: {
'Content-Type': 'application/json'
// 'Content-Type': 'application/x-www-form-urlencoded',
},
redirect: 'follow', // manual, *follow, error
referrerPolicy: 'no-referrer', // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url
body: JSON.stringify(data) // body data type must match "Content-Type" header
});
return response.json(); // parses JSON response into native JavaScript objects
}
postData('https://example.com/answer', { answer: 42 })
.then(data => {
console.log(data); // JSON data parsed by `data.json()` call
});
- 该示例涉及
async/await
语法,postData()
是一个异步函数,因为被标记为async
关键字 await fetch('url')
开始一个HTTP请求到url
URL,因为await
关键字的存在,异步函数被暂停,直到请求完成- 当请求完成过后,获取
response
,response.json().then(data)获取response中的Json文件数据
登录受控组件设计
现在我们可以开始着手创建我们自己的Login组件
一个简单的Login组件示例
function Login(){
return(
<div>This is Login page</div>
);
}
export default Login;
我们使用函数定义了名为Login的组件,在页面上显示返回值“This is Login page”
结合上述我们了解到的方法,我们可以开始构造复合组件
还是引用之前的页面展示:
登录操作:输入框中输入用户的Username, Password,点击Login按钮进行登录
我们设置<Input>
元素默认值为"",文本输入的操作会更改Input的值
可借助变更<Input>
元素的值,触发HTMLchange
事件,从而达到值的存储及后续函数调用
由于我们需要处理多个input的元素的,可参考以下方法写多个input的触发change事件
React handleChange() function explained - handle single/ multiple inputs
const [users, setUser] = useState({
username: '',
password: '',
});
const handleChange = (event) => {
const { name, value } = event.target
setUser({ ...users, [name]: value })
}
return (<div>
<Form>
<FormGroup>
<Label for="username">User Name</Label>
<Input type="text" name="username" id="username" value={users.username || ''}
onChange={handleChange} />
</FormGroup>
<FormGroup>
<Label for="password">Password</Label>
<Input type="password" name="password" id="password" value={users.password || ''}
onChange={handleChange} />
</FormGroup>
</Form>
</div>
)
标签:origin,V18,请求,登录,访问控制,React,Login,data,response
From: https://www.cnblogs.com/rinya09/p/17526417.html