注册流程
注册的前端:
- 1.前端的表达验证可以减轻服务器的负载,根据验证是否通过用DOM操作写页面特效
- 1.1邮箱或者手机号验证注册账号,绑定change事件,判读value值是否符合邮箱或者手机号的正则
- 1.2密码验证,绑定change事件,判读value值是否符合格式,比如密码必须包含英文大小写和数字,以及验证两次密码需要一致
- 1.3昵称验证,绑定change事件,判断value值是否符合格式,比如长度和不包含特殊字符等
- 1.4图片格式的验证以及图片文件的大小验证,然后做图片预览把用户选择的图片显示在页面上
- 2.给页面的提交按钮绑定点击事件,当用户点击提交按钮时获取用户交互信息
- 3.把数据用POST请求发送给后端服务器
- 4.等后端返回的数据,根据返回的数据包的业务码来操作不同的页面,当返回的数据包的业务码是正确的就跳转到登录页面或者直接帮用户登录
<body>
<input type="text" placeholder="请输入注册的邮箱" id="acount"> <br>
<input type="password" placeholder="请输入密码" id="pwd"> <br>
<input type="password" placeholder="请再次输入密码" class="pwd2">
<span id="pwdtext">两次输入的密码不一致</span>
<br>
<input type="text" placeholder="请输入昵称" id="screenname">
<div class="imgbox">
<p>请上传头像</p>
<input type="file" id="touxiang">
</div>
<p id="imgtext">图片格式不正确,只支持jpg、jpeg、png格式</p>
<p id="imgsize">图片大小必须大于10kb以及小于1M</p>
<button onclick="submit()">注册</button>
<script src="https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-M/axios/0.26.0/axios.js"
type="application/javascript"></script>
<script>
let flag = new Array(4).fill(true);
console.log(flag);
let acount = document.getElementById("acount");
acount.addEventListener("change", () => {
let reg = /^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/;
if (reg.test(acount.value)) {
acount.style.border = "2px green solid";
flag[0] = true;
} else {
acount.style.border = "2px red solid";
flag[0] = false;
}
});
let pwd = document.getElementById("pwd");
pwd.addEventListener("change", () => {
let reg = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[^]{8,16}$/;
if (reg.test(pwd.value)) {
pwd.style.border = "2px green solid";
flag[1] = true;
} else {
pwd.style.border = "2px red solid";
flag[1] = false;
}
});
let pwd2 = document.querySelector(".pwd2");
pwd2.addEventListener("change", () => {
document.querySelector("#pwdtext").style.visibility = "hidden";
if (pwd.value == pwd2.value) {
pwd2.style.border = "2px green solid";
flag[2] = true;
} else {
document.querySelector("#pwdtext").style.visibility = "visible";
pwd2.style.border = "2px red solid";
flag[2] = false;
}
});
let screenname=document.getElementById("screenname");
screenname.addEventListener("change",()=>{
let reg=/^([\u4e00-\u9fa5]{2,4})|([A-Za-z0-9_]{4,16})|([a-zA-Z0-9_\u4e00-\u9fa5]{3,16})$/;
if (reg.test(screenname.value)) {
screenname.style.border = "2px green solid";
flag[3] = true;
} else {
screenname.style.border = "2px red solid";
flag[3] = false;
}
});
let touxiang=document.getElementById("touxiang");
touxiang.addEventListener("change",()=>{
document.querySelector("#imgtext").style.visibility = "hidden";
document.querySelector("#imgsize").style.visibility = "hidden";
console.log(touxiang.files);
let urlobj=window.URL.createObjectURL(touxiang.files[0]);
document.querySelector(".imgbox").style.backgroundImage=`url("${urlobj}")`;
let arr=["image/png","image/jpg","image/jpeg"];
if(arr.includes(touxiang.files[0].type)){
flag[4] = true;
}else{
document.querySelector("#imgtext").style.visibility = "visible";
flag[4] = false;
}
if(10*1024<touxiang.files[0].size&&touxiang.files[0].size<1*1024*1024){
flag[4] = true;
}else{
document.querySelector("#imgsize").style.visibility = "visible";
flag[4] = false;
}
});
async function submit(){
if(flag.includes(false)){
}else{
let fdata=new FormData();
fdata.append("acount",acount.value);
fdata.append("password",pwd2.value);
fdata.append("screenname",screenname.value);
fdata.append("touxiang",touxiang.files[0]);
let resquest=await axios.post("/register",fdata);
console.log(resquest.data.code==4001)
if(resquest.data.code==2001){
window.location.href="/public/login/login.html";
}else if(resquest.data.code==4001){
alert(resquest.data.info);
window.location.href="/public/login/login.html"
}
}
}
</script>
</body>
注册的后端:
- 1.处理接收到的数据,把前端用户上传的文件处理成网络路径的字符串
- 2.将处理后的数据写入数据库
- 2.1下载egg-mysql插件并配置
- 2.2写代码操作MySQL数据库
async register() {
let ziduan=this.ctx.request.body;
let f1=this.ctx.request.files;
console.log(ziduan,f1);
for(let i=0;i<f1.length;i++){
let oldpath=f1[i].filepath;
let newpath=__dirname+"/../public/userdata/"+path.basename(oldpath);
if(f1[i]){
fs.copyFileSync(oldpath,newpath);
fs.unlink(oldpath,()=>{});
};
ziduan[f1[i].field]="/public/userdata/"+path.basename(oldpath);
console.log(ziduan);
}
let sqlselect=`SELECT * FROM user WHERE acount="${ziduan.acount}"`;
let sqlselectres=await this.app.mysql.query(sqlselect);
if(sqlselectres[0]){
this.ctx.body={info:"账号已注册",code:4001};
}else{
let create_time=new Date().toLocaleDateString();
let sqlinsert=`INSERT INTO user (acount,password,screenname,touxiang,create_time) VALUES ("${ziduan.acount}","${ziduan.password}","${ziduan.screenname}","${ziduan.touxiang}","${create_time}")`;
let sqlinsertres=await this.app.mysql.query(sqlinsert);
console.log(222222,sqlinsertres,111111);
this.ctx.body={info:"注册成功",code:2001};
}
}
登录的流程
登录的前端:
- 1.前端表单验证目的是减轻服务器的负载,根据验证是否通过用DOM操作写页面特效
- 1.1账号验证,账号是邮箱或者手机号,绑定change事件,判读value值是否符合邮箱或者手机号的正则
- 1.2密码验证,绑定change事件,判读value值是否符合指定的格式
- 2.用POST请求把账号和密码发送给后端—JWT
- 3.等后端返回数据,根据返回的数据包的业务码来操作不同的页面。
- 4.验证码
- 4.1当前端开始页面渲染时就请求验证码
- 4.2前端获取用户输入的验证码发送给后端
- 4.3前端根据收到的业务码来操作页面的业务
<body>
<style>
body {
background-image: url(../image/img-41.jpg);
background-size: 100%;
background-repeat: no-repeat;
}
.mobanbox {
width: 100%;
height: 100%;
background-color: rgba(202, 239, 247, 0.8);
position: fixed;
left: 0px;
top: 0px;
display: none;
}
.loginbox {
width: 500px;
height: 400px;
margin: 0 auto;
background-color: darkorchid;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.inputbox {
width: 200px;
height: 300px;
margin: 0 auto;
background-color: darkorchid;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
</style>
<button class="btn">点击进入登录窗口</button>
<div class="mobanbox">
<div class="loginbox">
<div class="inputbox">
<input type="text" placeholder="请输入注册的邮箱" id="acount"> <br>
<input type="password" placeholder="请输入密码" id="pwd"> <br>
<input type="text" class="verif">
<div class="yanzhengma"></div>
<button class="loginbtn">登录</button>
</div>
</div>
</div>
<script src="https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-M/axios/0.26.0/axios.js"
type="application/javascript">
</script>
<script>
let ver=document.querySelector(".yanzhengma");
function verifdata(){
axios.get("/verif")
.then((res=>{
console.log(res);
ver.innerHTML=res.data;
}));
};
verifdata();
ver.onclick=verifdata;
</script>
<script>
let btn = document.querySelector(".btn");
let mobanbox = document.querySelector(".mobanbox")
btn.onclick = function () {
mobanbox.style.display = "block";
};
let loginbtn = document.querySelector(".loginbtn");
loginbtn.onclick = async function () {
let flag = new Array(2).fill(true);
let acount = document.getElementById("acount");
acount.addEventListener("change", () => {
let reg = /^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/;
if (reg.test(acount.value)) {
acount.style.border = "2px green solid";
flag[0] = true;
} else {
acount.style.border = "2px red solid";
flag[0] = false;
}
});
let pwd = document.getElementById("pwd");
pwd.addEventListener("change", () => {
let reg = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[^]{8,16}$/;
if (reg.test(pwd.value)) {
pwd.style.border = "2px green solid";
flag[1] = true;
} else {
pwd.style.border = "2px red solid";
flag[1] = false;
}
});
let verif=document.querySelector(".verif");
if(flag.includes(false)){
alert("账号和密码格式不正确,请重新输入");
acount.value="";
pwd.value="";
}else{
let resquest=await axios.post("/login",{"acount":acount.value,"password":pwd.value,"verif":verif.value});
console.log(resquest);
if(resquest.data.code==2002){
window.location.href="/public/home.html";
}else if(resquest.data.code==4002){
alert("账号不存在,请先注册");
window.location.href="/public/register/register.html"
}else if(resquest.data.code==4003){
alert("密码错误,请重新输入");
pwd.value="";
pwd.focus();
}else if(resquest.data.code==4007){
alert(resquest.data.info);
verif.focus()
verif.value="";
verifdata();
}
}
};
</script>
</body>
登录的后端:
- 1.生成验证码并储存,然后把验证码发送给前端。
-
- 取出储存的验证码和接收前端发送的验证码以及将两者做比较,根据正确与否决定不同的业务,不正确就发送业务码给前端提示用户验证码输入有误,验证正确就验证前端发送的账号密码和数据库中的数据是否匹配,根据账号密码的匹配再发送不同的业务码给前端
const Controller = require('egg').Controller;
const svgCaptcha = require('svg-captcha');
class LoginController extends Controller {
async login() {
let ziduan = this.ctx.request.body;
console.log(ziduan);
let ver = this.ctx.cookies.get("verif");
if (ziduan.verif != ver) {
this.ctx.body = { info: "验证码输入有误", code: 4007 };
return;
}
let sqlselect = `SELECT * FROM user WHERE acount="${ziduan.acount}"`;
let sqlselres = await this.app.mysql.query(sqlselect);
if (sqlselres[0]) {
let sqlselpwd = `SELECT * FROM user WHERE acount="${ziduan.acount}" AND password="${ziduan.password}"`;
let sqlselpwdres = await this.app.mysql.query(sqlselpwd);
if (sqlselpwdres[0]) {
this.ctx.session.acount = ziduan.acount;
this.ctx.session.uid = sqlselpwdres[0].uid;
this.ctx.body = { info: "登陆成功", code: 2002 };
} else {
this.ctx.body = { info: "密码错误", code: 4003 };
}
} else {
this.ctx.body = { info: "账号不存在", code: 4002 };
}
}
async getUserInfo() {
let act = await this.ctx.service.database.islogin();
if (act) {
let acount = this.ctx.session.acount;
let sql1 = `SELECT touxiang,screenname FROM user WHERE acount="${acount}"`;
let sql1res = await this.app.mysql.query(sql1);
this.ctx.body = { info: "请求成功", code: 2004, ...sql1res[0] }
} else {
this.ctx.body = { info: "未登录", code: 4004 };
}
}
async verif() {
let captcha = svgCaptcha.create({
size: 4,
noise: 1,
color: true,
background: "Gold"
});
this.ctx.cookies.set("verif", captcha.text);
this.ctx.body = captcha.data;
}
async loginout() {
this.ctx.session.acount=null;
this.ctx.session.uid=null;
this.ctx.body={info:"退出登录成功"}
}
}
module.exports = LoginController;