目录
1 搭建新的项目文件
1.1 在我之前的学习笔记中有搭建的教程
可以自行按照之前的教程进行学习,这个项目是利用了一份前端的代码,然后我们在到里面进行请求或者其他功能的实现,因为我们主要是学习node,而不是画前端UI什么的。
2 完成发送注册时验证码功能
2.1 首先先接收请求的手机号码
//获取手机号码参数
let { phone } = req.query;
2.2 然后验证手机号码格式(正则表达式)
//验证手机号码格式
let isphone = /^(0|86|17951)?(13[0-9]|15[012356789]|16[6]|19[89]]|17[01345678]|18[0-9]|14[579])[0-9]{8}$/;
2.3 编写验证码方法
if (!isphone.test(phone)) {
res.send({ status: 400, "msg": "请输入正确的手机号码" });
return
}
2.4 查询手机号码
//查询数据库是否重复
let sql = "select count(1) as count from user where userPhone=?";
let count = await db.opreateDB(sql, [phone]);
2.5 验证信息
//验证数据库内是否重复
if (count > 0) {
//不存在就存入session,并发送验证码
} else {
//不存在就返回已被注册
}
2.6 将信息存session并发送验证码
//验证数据库内是否重复
if (count > 0) {
//不存在就存入session,并发送验证码
req.session.phone = phone;
req.session.code = code;
let code = getCode();
res.send({ status: 200, "msg": code });
} else {
//不存在就返回已被注册
res.send({ status: 400, "msg": "手机号已被注册。" })
}
2.7 完整代码
//编写跟用户相关的业务操作,注册、登录、修改信息。
const db = require('../util/dbconfig.js');
//注册方法
//发送验证码方法
async function sendCodeByPhone(req, res) {
//获取手机号码参数
let { phone } = req.query;
//验证手机号码格式
let isphone = /^(0|86|17951)?(13[0-9]|15[012356789]|16[6]|19[89]]|17[01345678]|18[0-9]|14[579])[0-9]{8}$/;
if (!isphone.test(phone)) {
res.send({ status: 400, "msg": "请输入正确的手机号码" });
return;
}
//查询数据库是否重复
let sql = "select count(1) as count from user where userPhone=?";
let count = await db.opreateDB(sql, [phone]);
//验证数据库内是否重复
if (count[0].count > 0) {
//存在就返回已被注册
res.send({ status: 400, "msg": "手机号已被注册" });
} else {
//不存在就存入session,并发送验证码
let code = getCode();
req.session.code = code;
req.session.phone = phone;
res.send({ status: 200, "msg": code });
}
}
//生成1000-9999的随机数
function getCode() {
return Math.floor(Math.random() * 9000 + 1000);
}
//暴露
module.exports = {
sendCodeByPhone,
register
};
3 完成账号注册功能
3.1 获取注册信息并且验证
//获取信息
let { nikename, pwd, repwd, phone, code } = req.query;
let insertsql = "INSERT INTO USER(userName,userPhone,userPwd) VALUES(?,?,?)";
let selectsql = "select count(1) as count from user where userPhone=?";
//查重
let phonecount = await db.opreateDB(selectsql, [phone]);
let sessioncode = req.session.code;
let sessionphone = req.session.phone;
//验证手机号码格式
let isphone = /^(0|86|17951)?(13[0-9]|15[012356789]|16[6]|19[89]]|17[01345678]|18[0-9]|14[579])[0-9]{8}$/;
if (!isphone.test(phone)) {
res.send({ status: 400, "msg": "手机号码格式不正确" });
return;
}
//验证验证码不等于四以及为字符
if (code.length != 4 || isNaN(code)) {
res.send({ status: 400, "msg": "验证码格式不正确" });
return;
}
//验证昵称不少于三位,最终解释权归程序员所有
if (nikename.length < 3) {
res.send({ status: 400, "msg": "昵称不能少于三位" });
return;
}
//验证密码不能少于六位
if (pwd.length < 6) {
res.send({ status: 400, "msg": "密码长度不能少于六位" });
return;
}
//验证两次密码是否一致
if (pwd != repwd) {
res.send({ status: 400, "msg": "两次密码输入不一致" });
return;
}
//验证注册手机号码是否重复
if (phonecount[0].count > 0) {
res.send({ status: 400, "msg": "手机号码已注册" });
return;
}
//请求的验证码与提交的验证码不一致
if (code != sessioncode) {
res.send({ status: 400, "msg": "验证码错误" });
return;
}
//验证手机号码和提交验证码的手机号码不一致
if (phone != sessionphone) {
res.send({ status: 400, "msg": "手机号码错误" });
return;
}
3.2 注册写入数据库中并且响应界面
//数据库注册注册
let count = await db.opreateDB(insertsql, [nikename, phone, pwd]);
/**
* count里面有几个参数
* fieldCount:现场计数
* affectedRows:受影响的行
* insertId:插入Id
* serverStatus:服务器状态
* warningCount:警告计数
* message:消息
* protocol41:协议41
* changedRows:更改的行
*/
//验证是否注册成功
if (count.affectedRows) {
res.send({ status: 200, "msg": "账号注册成功" });
return;
} else {
res.send({ status: 400, "msg": "账号注册失败" });
return;
}
3.3 完整代码
//注册方法
async function register(req, res) {
let { nikename, pwd, repwd, phone, code } = req.query;
let insertsql = "INSERT INTO USER(userName,userPhone,userPwd) VALUES(?,?,?)";
let selectsql = "select count(1) as count from user where userPhone=?";
//查重
let phonecount = await db.opreateDB(selectsql, [phone]);
let sessioncode = req.session.code;
let sessionphone = req.session.phone;
//验证手机号码格式
let isphone = /^(0|86|17951)?(13[0-9]|15[012356789]|16[6]|19[89]]|17[01345678]|18[0-9]|14[579])[0-9]{8}$/;
if (!isphone.test(phone)) {
res.send({ status: 400, "msg": "手机号码格式不正确" });
return;
}
//验证验证码不等于四以及为字符
if (code.length != 4 || isNaN(code)) {
res.send({ status: 400, "msg": "验证码格式不正确" });
return;
}
//验证昵称不少于三位,最终解释权归程序员所有
if (nikename.length < 3) {
res.send({ status: 400, "msg": "昵称不能少于三位" });
return;
}
//验证密码不能少于六位
if (pwd.length < 6) {
res.send({ status: 400, "msg": "密码长度不能少于六位" });
return;
}
//验证两次密码是否一致
if (pwd != repwd) {
res.send({ status: 400, "msg": "两次密码输入不一致" });
return;
}
//验证注册手机号码是否重复
if (phonecount[0].count > 0) {
res.send({ status: 400, "msg": "手机号码已注册" });
return;
}
//请求的验证码与提交的验证码不一致
if (code != sessioncode) {
res.send({ status: 400, "msg": "验证码错误" });
return;
}
//验证手机号码和提交验证码的手机号码不一致
if (phone != sessionphone) {
res.send({ status: 400, "msg": "手机号码错误" });
return;
}
//数据库注册注册
let count = await db.opreateDB(insertsql, [nikename, phone, pwd]);
/**
* count里面有几个参数
* fieldCount:现场计数
* affectedRows:受影响的行
* insertId:插入Id
* serverStatus:服务器状态
* warningCount:警告计数
* message:消息
* protocol41:协议41
* changedRows:更改的行
*/
//验证是否注册成功
if (count.affectedRows) {
res.send({ status: 200, "msg": "账号注册成功" });
return;
} else {
res.send({ status: 400, "msg": "账号注册失败" });
return;
}
}
4 完整代码
4.1 前端请求界面的完整代码
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>注册</title>
<link rel="stylesheet" href="css/base.css">
<link rel="stylesheet" href="css/register.css">
</head>
<body>
<header id="headNav">
<div class="innerNav cf">
<a class="fl" href="#"><img src="images/loginlogo.jpg" alt=""></a>
<div class="headFont fr">
<span>您好,欢迎光临1号店!<a href="loadpage.html">请登录</a></span>
<a class="helpLink" href="#"><i class="runbun"></i>帮助中心<i class="turnb"></i></a>
</div>
<div class="outHelp">
<ul class="helpYou" style="display: none;">
<li><a href="#">包裹跟踪</a></li>
<li><a href="#">常见问题</a></li>
<li><a href="#">在线退换货</a></li>
<li><a href="#">在线投诉</a></li>
<li><a href="#">配送范围</a></li>
</ul>
</div>
</div>
</header>
<section id="secTab">
<div class="innerTab">
<h2>1号店注册</h2>
<div class="tableItem">
<input type="text" name="phone" id="phone" required placeholder="手机号码" pattern="^1[3578]\d{9}$" />
</div>
<div class="cf">
<div class="tableItem onlyItem fl">
<input class="yanzheng" type="text" id="code" name="yanzheng" placeholder="验证码" />
</div>
<a class="tableText fr" href="#" id="iscode">获取验证码</a>
</div>
<div class="tableItem">
<input type="text" id="nikename" required placeholder="昵称" />
</div>
<div class="tableItem">
<input type="password" id="password" required placeholder="设置密码" pattern="^\w{6,10}$" />
</div>
<div class="tableItem">
<input type="password" id="rePassword" required placeholder="确认密码" pattern="^\w{6,10}$" />
</div>
<p class="clickRegist">点击注册,表示您同意1号店 <a href="#">《服务协议》</a></p>
<input type="submit" class="tableBtn" id="tableBtn" value="同意协议并注册">
</div>
</section>
<footer id="footNav">
<p><a href="#">沪ICP备13044278号</a>| 合字B1.B2-20130004 |<a href="#">营业执照</a></p>
<p>Copyright © 1号店网上超市 2007-2016,All Rights Reserved</p>
</footer>
</body>
<script src="js/jquery-1.11.1.min.js"></script>
<!-- <script src="js/register.js"></script> -->
<script>
$(function () {
let indexTime = 60;//发送验证码请求时间
let send = true;//禁止短时间内重复提交
//获取验证码点击事件处理
$("#iscode").click(function () {
//处理this指向问题
let _this = this;
//获取手机号码信息
let phone = $("#phone").val();
//验证手机号码格式
let isphone = /^(0|86|17951)?(13[0-9]|15[012356789]|16[6]|19[89]]|17[01345678]|18[0-9]|14[579])[0-9]{8}$/;
if (!isphone.test(phone)) {
alert("手机号码格式不正确");
return;
}
//发送请求验证码
if (!send) {
console.log("禁止重复提交");
return;
}
send = false;
$.ajax({
url: "http://localhost/users/send?phone=" + phone,
dataType: "json",
type: "get",
success: function (data) {
if (data.status == 200) {
console.log(data.msg);
alert("您的参数为" + data.msg);
let Timers = setInterval(function () {
indexTime--;
if (indexTime <= 0) {
indexTime = 60;
$(_this).text(`重新发送`);
//停止时间函数运行
clearInterval(Timers);
send = true;
} else {
$(_this).text(`(${indexTime})重新发送`);
}
}, 1000);
} else {
//请求验证码失败
alert(data.msg);
send = true;
}
}
})
});
//点击提交注册事件
$("#tableBtn").click(function () {
//获取信息并验证
let phone = $("#phone").val();//手机号码
let code = $("#code").val();//验证码
let nikename = $("#nikename").val();//昵称
let password = $("#password").val();//密码
let rePassword = $("#rePassword").val();//确认密码
//验证手机号码格式
let isphone = /^(0|86|17951)?(13[0-9]|15[012356789]|16[6]|19[89]]|17[01345678]|18[0-9]|14[579])[0-9]{8}$/;
if (!isphone.test(phone)) {
alert("手机号码格式不正确");
return;
}
//验证验证码不等于四以及为字符
if (code.length != 4 || isNaN(code)) {
alert("验证码格式不正确");
return;
}
//验证昵称不少于三位,最终解释权归程序员所有
if (nikename.length < 3) {
alert("昵称不能少于三位");
return;
}
//验证密码不能少于六位
if (password.length < 6) {
alert("密码长度不能少于六位");
return;
}
//验证两次密码是否一致
if (password != rePassword) {
alert("两次密码输入不一致");
return;
}
//请求提交ajax
$.ajax({
url: `http://localhost:80/users/register?phone=${phone}&code=${code}&nikename=${nikename}&pwd=${password}&repwd=${rePassword}`,
dataType: "json",
type: "get",
success: function (data) {
console.log(data);
let status = data.status;
if (status === 200) {
//请求成功
let faly = confirm("注册成功,是否跳转到登录界面");
if (faly) {
location.href = "loadpage.html";
}
} else {
//请求失败
alert(data.msg);
}
}
});
});
});
</script>
</html>
4.2 服务器注册相关完整代码
//编写跟用户相关的业务操作,注册、登录、修改信息。
const db = require('../util/dbconfig.js');
//注册方法
async function register(req, res) {
let { nikename, pwd, repwd, phone, code } = req.query;
//写入数据库的sql语句
let insertsql = "INSERT INTO USER(userName,userPhone,userPwd) VALUES(?,?,?)";
//查重的sql语句
let selectsql = "select count(1) as count from user where userPhone=?";
//查重
let phonecount = await db.opreateDB(selectsql, [phone]);
//存入session的数据
let sessioncode = req.session.code;
let sessionphone = req.session.phone;
//验证手机号码格式
let isphone = /^(0|86|17951)?(13[0-9]|15[012356789]|16[6]|19[89]]|17[01345678]|18[0-9]|14[579])[0-9]{8}$/;
if (!isphone.test(phone)) {
res.send({ status: 400, "msg": "手机号码格式不正确" });
return;
}
//验证验证码不等于四以及为字符
if (code.length != 4 || isNaN(code)) {
res.send({ status: 400, "msg": "验证码格式不正确" });
return;
}
//验证昵称不少于三位,最终解释权归程序员所有
if (nikename.length < 3) {
res.send({ status: 400, "msg": "昵称不能少于三位" });
return;
}
//验证密码不能少于六位
if (pwd.length < 6) {
res.send({ status: 400, "msg": "密码长度不能少于六位" });
return;
}
//验证两次密码是否一致
if (pwd != repwd) {
res.send({ status: 400, "msg": "两次密码输入不一致" });
return;
}
//验证注册手机号码是否重复
if (phonecount[0].count > 0) {
res.send({ status: 400, "msg": "手机号码已注册" });
return;
}
//请求的验证码与提交的验证码不一致
if (code != sessioncode) {
res.send({ status: 400, "msg": "验证码错误" });
return;
}
//验证手机号码和提交验证码的手机号码不一致
if (phone != sessionphone) {
res.send({ status: 400, "msg": "手机号码错误" });
return;
}
//数据库注册注册
let count = await db.opreateDB(insertsql, [nikename, phone, pwd]);
/**
* count里面有几个参数
* fieldCount:现场计数
* affectedRows:受影响的行
* insertId:插入Id
* serverStatus:服务器状态
* warningCount:警告计数
* message:消息
* protocol41:协议41
* changedRows:更改的行
*/
//验证是否注册成功
if (count.affectedRows) {
res.send({ status: 200, "msg": "账号注册成功" });
return;
} else {
res.send({ status: 400, "msg": "账号注册失败" });
return;
}
}
//发送验证码方法
async function sendCodeByPhone(req, res) {
//获取手机号码参数
let { phone } = req.query;
//验证手机号码格式
let isphone = /^(0|86|17951)?(13[0-9]|15[012356789]|16[6]|19[89]]|17[01345678]|18[0-9]|14[579])[0-9]{8}$/;
if (!isphone.test(phone)) {
res.send({ status: 400, "msg": "请输入正确的手机号码" });
return;
}
//查询数据库是否重复
let sql = "select count(1) as count from user where userPhone=?";
let count = await db.opreateDB(sql, [phone]);
//验证数据库内是否重复
if (count[0].count > 0) {
//存在就返回已被注册
res.send({ status: 400, "msg": "手机号已被注册" });
} else {
//不存在就存入session,并发送验证码
let code = getCode();
req.session.code = code;
req.session.phone = phone;
res.send({ status: 200, "msg": code });
}
}
//生成1000-9999的随机数
function getCode() {
return Math.floor(Math.random() * 9000 + 1000);
}
//暴露
module.exports = {
sendCodeByPhone,
register
};
4.3 数据库的完整代码
/*
SQLyog Ultimate v12.4.1 (64 bit)
MySQL - 5.7.31-log : Database - liudb
*********************************************************************
*/
/*!40101 SET NAMES utf8 */;
/*!40101 SET SQL_MODE=''*/;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
CREATE DATABASE /*!32312 IF NOT EXISTS*/`liudb` /*!40100 DEFAULT CHARACTER SET utf8 */;
USE `liudb`;
/*Table structure for table `user` */
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`userId` int(11) NOT NULL AUTO_INCREMENT,
`userName` varchar(20) DEFAULT NULL,
`userPhone` varchar(11) DEFAULT NULL,
`userPwd` varchar(20) DEFAULT NULL,
PRIMARY KEY (`userId`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
/*Data for the table `user` */
insert into `user`(`userId`,`userName`,`userPhone`,`userPwd`) values
(1,'admin','18888888888','123'),
(2,'dowson','18888888888','123');
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
5 值得注意
5.1 设置路由
记得要设置好路由,我的路由是这样子的
var express = require('express');
var router = express.Router();
var userController = require('../controller/userController.js');
/* GET users listing. */
router.get('/send', userController.sendCodeByPhone);
router.get('/register', userController.register);
module.exports = router;
5.2 数据的验证
数据验证是首位,第一想到的就应该是数据验证,而且验证不仅请求验证码时要验证,请求注册也需要验证,以及前端发起请求前也需要验证,这是保证数据安全有序的重要部分。
6 结束
我们的注册功能就完整地实现了。