node+express项目案例(一):https://blog.csdn.net/Chris__wang/article/details/90738551
node+express项目案例(二):https://mp.csdn.net/postedit/90738794
node+express项目案例(三):https://mp.csdn.net/postedit/90744140
项目地址:https://github.com/wangyeky3419/node-app
数据库用的是mysql数据库,表内数据会放在代码中
本项目虽然页面不多,但是包含了基本的数据库建立,查询,修改,删除,插入,路由管理以及artTemplate模板应用,页面登录,cookie登录用户信息存储,md5密码加密等
前面已经介绍了页面的基本样式,下面开始介绍一下代码部分
项目的整体架构如上图
README.md
# bin 项目的启动文件,也可以放其他脚本
# node_modules 项目依赖
# public 存放静态文件(css, js, img)
# routes 路由控制器
# views 视图目录 (暂时没用上)
# template 模板放的位置
# app.js 项目入口及程序启动文件
# package.json 配置信息
由于没用涉及到文件上传,故而static目录暂时也没有用上,目录结构很清晰简单
首先介绍app.js 项目入口 注:文件中有些中间件暂时没用用上,但是后期可能会用上,所以没用删除
1. 安装node环境
2. 根据引入的中间件下载依赖 如npm install express express-static .... --save
var express = require('express');//express框架
var static = require('express-static')//接受一个参数,就是静态资源文件所在的目录,也就是文件读取
var bodyParser = require('body-parser');//能够解析数据类的post,但是对于文件上传类型的post不能解析,所以他有点不好
var multer = require('multer');//解析post文件
var cookieParser = require('cookie-parser');
var cookieSession = require('cookie-session');
//创建一个multer对象,指明文件上传到哪个目录
const multerObj = multer({dest:'./static/upload'})
// var consolidate = require('consolidate');//----------------------
var atrTemplate = require('express-art-template')
const expressRoute = require('express-route');
var path = require('path');//解析文件路径
var favicon = require('serve-favicon');
var server = express();//创建服务
server.listen(8080);
var router = express.Router();
//1.获取前台请求数据
//get
server.use(bodyParser.urlencoded())//解析post数据的req.body数据,不然解析不出来会报错
server.use(multerObj.any())
//2. cookie session
server.use(cookieParser())
server.use(cookieParser());
(function(){
//防止被污染变量,用一个函数包起来
var keys = [];
for(var i = 0; i < 10000; i++){
keys[i]='a_'+Math.random()
}
server.use(cookieSession({
name:'session_id',
keys:keys,
maxAge:20*60*1000//20min后过期
}));
})()
server.use(express.static(__dirname+'/public/'))//将静态文件目录指定到public下
server.use(express.static(__dirname+'/template/'))//将每个页面的静态文件目录指定到template下
//======================模板================================
//将指定的art文件渲染成html(art)文件
server.engine('art',atrTemplate);
//模板文件放在哪,这里的views是固定写法,指定模板文件位置(这里是放在template里)
server.set('views','./template');
//输出什么东西,view engine(写法固定,意思是视图引擎),这里设置的是输出html
server.set('view engine','html');
//======================route路由==========================
//创建route放在routes文件夹中 route必须用use 不能用get
server.use('/',require('./routes/index.js')())//当访问根目录的时候,跳转到routes/index.js文件里的route
// server.use('/login',require('./routes/web/login.js')())//当访问login目录的时候,跳转到web/login.js文件里的route里
代码中注释写的非常清楚了,所以文章里就不过多介绍了
接着是跳转到routes下
其中routes下index.js是主路由,login.js news.js user.js分别是对应页面的路由,
index.js
const express = require('express');
const urlLib = require('url');
module.exports = function(){
var router = express.Router();
//检查登录状态,如更没登录,跳转到登录状态
router.use((req,res,next)=>{//没有登录
if(req.url!='/favicon.ico'){
var pattern = new RegExp("/", "g");
var reqUrl = req.url.replace(pattern,'');
reqUrl = '/'+reqUrl
if(!req.session['admin_id']&&reqUrl!='/login'){
//这里检查如果没有登录(没有admin_id)就会重定向到登录界面
//当登录后,就会设置admin_id
res.redirect('/login');//重定向
//备注,重定向后还是会重新访问这里文件,这时候还会做判断,如果判断失败,走else
}else{
next()
}
}
});
router.get('/',(req,res)=>{
res.render('index.art',{
path:'./user/user.art'
})
})
//当访问login,跳转到login路由,进行登录页面渲染
router.use('/login',require('./login.js')());
//当访问user,跳转到user路由,进行user.art渲染
router.use('/user',require('./user.js')());
//当访问news,跳转到news路由,进行news.art渲染
router.use('/news',require('./news.js')());
return router;
}
在index.js里面检查登录状态时,经常会有其他路径干扰,故而加上了过滤,这里如果有大神有好办法,也希望指教一下,
routes/login.js
const express = require('express');
const mysql = require('mysql');
const utils = require('../public/utils/md5.js')//引入md5
var db = mysql.createPool({
host:'localhost',
user:'root',
password:'9527',
database:'learn'
});
module.exports = function(){
var router = express.Router();
//当请求方式为get的时候,约定为访问页面
router.get('/',(req,res)=>{
res.render('login/login.art',{});
})
//当请求方式为post的时候,约定为登录操作
router.post('/',(req,res)=>{
var username = req.body.userName;
//将获取的密码转成md5加密形式,而且数据库存的也是加密后的,并且有后缀
var password = utils.md5(req.body.password+utils.MD5_SUFFIX);
db.query(`SELECT * FROM admin_table WHERE username='${username}'`,(err,data)=>{
if(err){
res.status(500).send('服务器出错').end()
}else{//成功
if(data.length == 0){
res.status(400).send('该用户不存在').end()
}else{//成功且有值
if(data[0].password == password){//对比的是md5后的值
//给session赋值
req.session['admin_id'] = data[0].ID;
//重定向到首页
res.redirect('/')
}else{
res.status(400).send('密码不正确')
}
}
}
})
})
//注册register
router.post('/register',(req,res)=>{
var username = req.body.userName;
//将获取的密码转成md5加密形式,而且数据库存的也是加密后的,并且有后缀
var password = utils.md5(req.body.password+utils.MD5_SUFFIX);
//注册部分
})
return router;
}
注册部分由于时间问题没写完,这里跟普通的数据库增加数据一样,只不过是增加了一个md5密码加密
路由部分的user.js news.js跟这也一样
下面是模板部分。这里用的是.art扩展名,index.art是首页包含导航部分,其余分别是下属子页面,其中如果js和css代码如果不多,我就直接写在art文件里了,并没有外部引用。
template/login/login.art
登录
template/index.art 可以对应上面的routes/index.js看
Chris_Wang
{{include $data['path'] $data}}
注:代码中部分类名如mr-sm-2 my-2等是bootstrap4里面新增加的实用性工具类,详见
https://v4.bootcss.com/docs/4.0/getting-started/introduction/
中文文档:https://cloud.tencent.com/developer/doc/1018
未完待续。。。