(啊对,因为只是演示,所以几乎没有加任何样式和美化,css样式等整个项目完成度比较高了再考虑弄)
初次访问网站时,后端没有检查到cookie,于是自动跳转至登录页面
点击“注册账号”后跳转至注册页面
身份选择为教师时会多出验证码一项。(此处验证码暂时是固定的)
如果输入的信息有误,会根据错误信息进行对应的提示。
如果注册信息无误则会显示注册成功,并有一个返回首页的按钮
返回首页后回到登陆页面,正确输入账号密码,即显示登陆成功(否则也会进行错误提示)
再点击返回首页,由于登陆时创建了cookie,首页不再跳转至登录页面,而是根据cookie信息显示了当前的用户名和身份。
点击“注销账号”后,后端清除cookie并再次访问首页,于是又跳转到了登陆页面。
代码上主要由三个路由和对应的三个ejs模板页面实现。
很明显,index,login和register分别对应了首页、登陆页面和注册页面,路由(js)实现后端逻辑,ejs实现前端页面。
index.js,根据有无cookie产生不同的响应,并处理“注销账号”的请求,具体看代码
var express = require('express');
var router = express.Router();
//捕获到get请求(即访问127.0.0.1:3000)
router.get('/', function(req, res, next) {
let coo=req.cookies;
//检查是否存在cookie,若没有则跳转至登陆页面
if (coo.username==undefined)
{
res.redirect('/login');
}
//若有,则将cookie信息作为参数传递给index.ejs进行渲染
else
{
//cookie中身份信息存放的是'0'和'1',转化为'学生'和'教师'
var loginType='';
if (coo.loginType=='0') loginType="学生";
else loginType="教师"
res.render('index',{username:coo.username,loginType:loginType});
}
});
//捕获到post请求
router.post('/',function(req,res,next){
let bod=req.body;
//“注销账号”按钮被点击时
if (bod.refresh=='1'){
//清除所有cookie
res.clearCookie('username');
res.clearCookie('loginType');
//重新跳转至首页
res.redirect('/');
}
})
module.exports = router;
index.ejs,username和loginType是两个参数,用来显示用户信息
<html>
<head>
head>
<body>
<h1>首页h1>
<p>当前的账号为:<%= username%>p>
<p>身份:<%= loginType%>p>
<form method="post">
<button type="submit" name="refresh" value="1">注销账号
form>
body>
html>
login.js通过MySQL验证登录是否有效,若有效则创建cookie,跳转至欢迎页面
var express = require('express');
var router = express.Router();
var mysql=require('../mysql.js')
//初次访问
router.get('/login',function(req,res){
//不显示错误
res.render('login',{fail:0});
})
router.post('/login',function(req,res){
var info=req.body;
//MySQL检查账号密码正确性
var fetchSql="SELECT username,passwords,loginType from login where username='"+info.username
+"' and passwords='"+info.passwords+"';";
mysql.query(fetchSql,function(err,results,fields){
//账号不存在,返回错误
if (results.length==0){
res.render('login',{fail:1});
}
//账号存在
else{
//创建账号信息cookie,results[0]指向当前用户信息
let now=results[0];
res.cookie('username',now.username);
res.cookie('loginType',now.loginType);
//根据用户身份,跳转至不同的欢迎界面
if (now.loginType=='0')
{
res.sendfile('public/studentLoginSuccess.html');
}
if (now.loginType=='1')
{
res.sendfile('public/teacherLoginSuccess.html');
}
}
})
})
module.exports=router;
login.ejs fail参数用于决定是否提示错误
<body>
<h1>登陆页面h1>
<form method="post">
<div>
<label>用户名:label>
<input name="username" type="text">
div>
<div>
<label>密码:label>
<input name="passwords" type="password">
div>
<br>
<button name="login" type="submit">登陆button>
form>
<a href='../register'>注册账号a>
<div id="show">div>
<script>
//显示错误信息
var fail=<%= fail %>;
if (fail) document.getElementById("show").innerText="账号密码有误~";
script>
body>
register.js 逐条验证注册信息是否有效,有效则将数据插入MySQL数据库中,否则返回相应的错误信息
var express = require('express');
var router = express.Router();
var mysql=require('../mysql.js')
router.get('/register',function(req,res){
//5个tip分别对应五种错误信息,初次访问时错误信息都为空
res.render('register',{tip1:'',tip2:'',tip3:'',tip4:'',tip5:''});
});
router.post('/register',function(req,res){
var info=req.body;
//正则表达式,检验字符串是否只由数字、字母和下划线组成
var exp=/^\w+$/;
var tip1='',tip2='',tip3='',tip4='',tip5='';
//检验用户名合法性
if (!exp.test(info.username) || info.username.length>15 || info.username.length<6) tip1="请输入正确的用户名~";
//检验密码合法性
if (!exp.test(info.passwords) || info.passwords.length>18 || info.passwords.length<6) tip2="请输入正确的密码~";
//检验两次密码是否一致
if (info.passwords!=info.passwordsChecker) tip3="两次密码不一致~";
//若身份为教师,验证码是否正确
if (info.loginType=='1' && info.identify!="lyflyf") tip4="验证码有误~";
//检验该用户名是否已被注册
var fetchSql="SELECT id FROM login WHERE username='"+info.username+"';"
mysql.query(fetchSql,function(err,results,fields){
if (results.length!=0) tip5="该用户名已被注册~";
//注册信息至少有一项存在错误,返回注册页面并提示错误
if (tip1 || tip2 || tip3 || tip4 ||tip5)
res.render('register',{tip1:tip1,tip2:tip2,tip3:tip3,tip4:tip4,tip5:tip5});
else
//没有错误
{
//将数据写入MySQL
var insertSql="INSERT INTO login(username,passwords,loginType)"+
"VALUES('"+info.username+"','"+info.passwords+"',"+info.loginType+");";
mysql.query(insertSql,function(err,results,fields){
if (err) console.log("插入失败~");
else
//注册成功,跳转至成功页面
res.sendfile("public/registerSuccess.html");
})
}
})
})
module.exports = router;
register.ejs 参数tip1至tip5,分别对应五种错误信息,若无误则tip为’’
<head>
<style>
.tip{
display:inline;
color:red;
};
style>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js">script>
<script>
//控制“验证码”一行的可见性
function invisible(){
$('#identifier').attr('style','display:none');
};
function visible(){
$('#identifier').attr('style','display:inline');
};
script>
head>
<body>
<h1>注册页面h1>
<form method="post">
<div>
<label>输入账号:label>
<input name="username" type="text">(由6-15位字母,数字和下划线组成)
<br><p class="tip"><%= tip1%>p><br>
div>
<div>
<label>输入密码:label>
<input name="passwords" type="password">(由6-18位字母,数字和下划线组成)
<br><p class="tip"><%= tip2%>p><br>
div>
<div>
<label>确认密码:label>
<input name="passwordsChecker" type="password">
<br><p class="tip"><%= tip3%>p><br>
div>
<div>
<label>选择身份:label>
学生<input type="radio" name="loginType" id="student" value="0" onclick="invisible()">
教师<input type="radio" name="loginType" id="teacher" value="1" onclick="visible()">
<br><br>
div>
<div id='identifier' style="display:none">
<label>输入验证码:label>
<input name="identify" type="text">
<br><p class="tip"><%= tip4%>p><br>
div>
<button name="return" onclick="window.open('/login')">返回button>
<button name="register" type="submit">提交注册button>
<br><p class="tip"><%= tip5%>p><br>
form>
body>
自我总结一下,讲的会比较乱,可以暂时不看。
对于express框架一个非常基础但是非常重要的理解是:app.js是代码唯一的入口。至于为什么之前都是通过运行\bin\www来创建服务器呢,大概是因为www是一个可执行文件吧,但是我们完全可以在app.js中加上以下三行代码然后删掉\bin\www
var http = require('http');
var server = http.createServer(app);
server.listen(3000)
这样以后直接执行app.js即可创建服务器
有了以上这个认知以后,或多或少会觉得思路清楚了一些。
再去看其他几个文件夹的内容
node_modules存放的是安装的各种模块,无视。
public存放一些静态的html或者图片资源,直接调用即可。
重点来了,routers,中文是路由器,充当的也的确是路由器的作用。所有对于网页的请求都可以通过路由器来处理,为了代码结构的清晰,对于每一块相对独立的功能(比如这次做的首页、登录、注册三个功能),都可以创建一个各自的路由器。在路由器内部,我们再对post请求、get请求,以及包含在请求内的信息分类进行处理,并分别返回。其中各类请求包含的信息存放在req中,返回则通过res的各种方法。
举几个栗子:req.cookies获取cookies,req.body获取参数。
res.sendfile发送页面,res.download发送下载文件,res.render渲染并发送ejs,res.clearCookie清除cookie,等等等。
reference:http://www.360doc.com/content/18/0422/07/32517277_747703104.shtml
另一个重点则是ejs,可以说是一种容易理解,写起来又很方便的模板。只需要通过res.render()就可以像函数一样,将一些参数传递给前端页面。
此时再回到代码的入口,即app.js,只需要用app.use引入路由(router对象),就等同于将某个功能并入了整个网站。
就像这样子
var loginRouter = require('./routes/login');
var registerRouter = require('./routes/register');
var indexRouter = require('./routes/index');
app.use('/',loginRouter);
app.use('/',registerRouter);
app.use('/',indexRouter);
总之router和ejs使得代码的结构相当清晰。