express路由模块化-总结

本文介绍了如何将路由和接口从app.js中拆分,创建了独立的登录和商品模块,详细描述了路由结构、文件迁移过程和关键API实现。涉及到使用Express、路由管理、静态文件服务及会话管理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#现在基本上整个增删改查都有了,但是我们发现所有路由和接口api全部写在app.js里面,现在我们把路由拆分出来,单独建立文件夹,用来存储路由和视图ejs,方便后期的维护
大概目录如下
image.png
路由架构/js
登录路由 — router-login
商品路由 — router-product
其他路由 — router-other
商品页面/ejs
公共页面 — views-public-header.ejs
登录页面 — views-login-login.ejs
商品页面 ---- views-product
—商品列表—list.ejs
—商品新增—add.ejs
—商品编辑—edit.ejs
其他页面 — views-other-other.ejs
image.png

1:先来拆分路由吧
新建一个router文件夹,分别建立login、product文件夹
login中新建login.js实现路由,代码如下

let  express = require('express');
let router = express.Router();  //路由拆分使用
const  app = express();
//这里就不是app.get啦全部用router来接管啦
router.get("/",(req,res)=>{
	res.render("login/login");
});

router.get("/login",(req,res)=>{
	res.render("login/login");
});
//导出去暴露使用
module.exports = router;

2:在app.js中引入使用

//路由封装
var  login=require('./router/login/login.js');
//express的自定义路由Router
//login全部去寻找login这个模块里面 再具体定义就好了
//login/ 
//login/user  
//login/pic
app.use('/login',login);  //去寻找login.js这个里面匹配

效果如下
image.png
ps:类似于在路由前面加了一个前缀/login
对,就是这样理解就对啦,现在我们把登录所有的功能移过来

let  express = require('express');
let router = express.Router();
const  app = express();
var md5=require("md5-node");
//解析post提交的数据 
const  bodyParser = require('body-parser')
router.use(bodyParser.urlencoded({ extended: false }))
router.use(bodyParser.json())

const  ejs = require('ejs');
const session = require("express-session");
//设置cookie参数
app.use(session({
  secret: 'keyboard cat',
  resave: false,
  saveUninitialized: true,
  cookie: { maxAge: 30*60*1000 },
  rolling:true
}))
//数据库操作
var DB =require('../../module/db.js');

//静态文件服务  容易出错2  是express 
app.use(express.static('public'))

//映射upload为虚拟目录,去upload里面寻找图片
app.use('/upload',express.static('upload'))

router.get("/",(req,res)=>{
	res.render("login/login");
});

router.get("/login",(req,res)=>{
	res.render("login/login");
});

//表单提交的后台接口
router.all('/doLogin',(req,res)=>{
	let username = req.body.username;
	let password = md5(req.body.pwd);
	console.log(`${username}---${password}`);
	//var body= { 'username': 'admin', 'pwd': '123456' };
	console.log(req.body);//{ username: 'admin', pwd: '123456' }
	//数据库操作 
	DB.find("user",{
			username:username,
			pwd:password
	},function(err,data){
		if(data.length>0){
		 		//console.log("登录成功");
		 		req.session.userinfo= data[0];
		 		//ejs 全局设置数据,其他页面可以共用
				//app.locals.userinfo=data[0]; 分开后无法这样使用 
				var  userinfo =req.session.userinfo;
		 		console.log('userinfo=====>'+userinfo);
		 		res.redirect("/product/list");
		 	}else{
		 		console.log("登录失败");
		 		res.send("<script>alert('登录失败');location.href='/login/login'</script>")
		 	}
	});
});

//退出
router.all("/loginOut",(req,res)=>{
	req.session.destroy((err)=>{
		if(err){
			console.log(err);
		}else{
			res.redirect('/login/');
		}
	})
});

module.exports = router;

ps:这里我遇到了几个小问题,需要注意点
1:所有的app.use和app.post都得改成router.use和router.all,方便接管路由
2:所有的路径问题,静态资源库css、图片路径、接口路径都得修改
image.png
3:session问题,我在这里卡了很久终于解决了
image.png
开始一直报错,找不到userinfo,尝试用redirect传递,发现无法使用没有这个api,然后想着用render这里直接渲染list页面,但是发现又得查询一遍数据库,比较麻烦,后来又想用本地存储存储storage来实现,发现有点麻烦,主要是不想在ejs里面写js代码,后面一步步调试,决定用req来传递,发现登录页面成功后,list页面虽然是include引入了header这个模块,也是可以获取到req里面的对象,所以最后决定直接获取,本来想用 //app.locals.userinfo=data[0]; 分开后无法这样使用,这个自带的locals对象的,发现编译一直报错,找不到,就算用router接管传递也不行,最后放弃,主要是没时间折腾了

最后效果图
image.png

登录模块弄完了,接下来弄商品模块
根据功能,分别拆分接口,新建文件夹存储单独的模块视图ejs,这里用一个product.js来存储所有商品的相关api接口和路由,代码如下

let  express = require('express');
const  app = express();
let router = express.Router();
//图片上传
var multiparty = require('multiparty');
var http = require('http');
//var util = require('util');

//数据库操作
var DB =require('../../module/db.js');

//静态文件服务  容易出错2  是express 
router.use(express.static('public'))
//映射upload为虚拟目录,去upload里面寻找图片
router.use('/upload',express.static('upload'))


router.get("/",(req,res)=>{
	res.send("product  index")
});

//商品列表
router.all("/list",(req,res)=>{		
	DB.find('shop',{},function(err,data){
		//if(data.length>0){
		 	res.render("product/list",{shopList:data,userinfo:req.session.userinfo});
		//}else{
		//	res.render("productList");
		//}
	});
});


//商品增加
router.all("/add",(req,res)=>{
	res.render("product/add")
});

router.all("/edit",(req,res)=>{
	res.render("product/edit")
});
router.all("/del",(req,res)=>{
	res.send("product/delete")
});






//商品新增接口
router.all("/shopAdd",(req,res)=>{
	var form = new multiparty.Form();
	//配置文件上传目录,后续需要映射虚拟目录才可以显示
	form.uploadDir = "upload";//新建一个upload目录,专门存储上传图片
	
	form.parse(req, function(err, fields, files) {
		//console.log(fields);
		//console.log(files);
		let  shopname= fields.shopname[0];	
		//图片路径 注意是files
		let  shoppic = files.shoppic[0].path;
		let  shopprice = fields.shopprice[0];
		let  shopfee = fields.shopfee[0];	
		let  shopDesc = fields.shopDesc[0];
		//console.log(shopname);
		//console.log(shoppic);
		//console.log(shopprice);
		//console.log(shopfee);
		//console.log(shopDesc);
		//插入数据库
		DB.insert('shop',{
				title:shopname,
				pic:shoppic,
				price:shopprice,
				fee:shopfee
				
			},(err,data)=>{
			//if(!err){
				res.redirect("/product/list")
			//}
		})

	})
	
});


//商品修改初始化页面
router.all("/shopEdit",(req,res)=>{
	//获取id
	let  id =req.query.id;
	console.log(id);
	//查询数据
	DB.find('shop',{_id:new DB.objectId(id)},(err,data)=>{
		//console.log(data[0]);
		//console.log(data);
		//渲染修改视图页面
		res.render('product/edit',{shopList:data[0]})
	})
});

//商品修改接口提交修改
router.all("/doshopEdit",(req,res)=>{
	
	var form = new multiparty.Form();
	//配置文件上传目录,后续需要映射虚拟目录才可以显示
	form.uploadDir = "upload";//新建一个upload目录,专门存储上传图片
	
	form.parse(req, function(err, fields, files) {
		//console.log(fields);
		//先拿到修改的ID,更新使用
		let _id = fields._id[0];
		console.log(_id);
		let  shopname= fields.shopname[0];	
		//图片路径 注意是files
		let  shoppic = files.shoppic[0].path;
		let  shopprice = fields.shopprice[0];
		let  shopfee = fields.shopfee[0];	
		let  shopDesc = fields.shopDesc[0];
		console.log(files);
		//console.log(shoppic);
		//console.log(shopprice);
		//console.log(shopfee);
		//console.log(shopDesc);
		//单独处理图片
		let  orginFileName =files.shoppic[0].originalFilename;
		if(orginFileName){//有修改图片
			var setData={
				title:shopname,
				pic:shoppic,
				price:shopprice,
				fee:shopfee
			}
		}else{  //没有修改图片就不添加
			var setData={
				title:shopname,
				price:shopprice,
				fee:shopfee
			}	
		}
		//删除临时文件
		//fs.unlink(shoppic,(err)=>{console.log(err)});
		
		//根据id修改更新数据库
		DB.update('shop',{"_id":new DB.objectId(_id)},setData
				,function(err,data){
					if(!err){
              res.redirect('/product/list');
          }
				}
		);
		

	})
});

//删除文件
router.all("/shopDel",(req,res)=>{
	let _id= req.query.id;
	console.log("_id==="+_id);
	//根据id修改更新数据库
	DB.deleteOne('shop',{"_id":new DB.objectId(_id)}
			,function(err){
				if(!err){
					res.redirect('/product/list');	
               	 	console.log("删除成功");
            	}
			}
	);
	
});

module.exports = router;

ps:这个还算顺利,没遇到什么麻烦,基本只要修改接口地址和路径,不会有太大的问题,不过这渲染list页面的时候,需要把登录的userinfo传递过来,否则获取不到登录名哦
image.png

最后按步骤提取add.edit.remove等ejs放到对应目录
最后再来看看app.js,修改完之后,很清爽吧

const  express =require('express');
const  app = express();

const  ejs = require('ejs');

var fs = require("fs");
const session = require("express-session");
//设置cookie参数
app.use(session({
  secret: 'keyboard cat',
  resave: false,
  saveUninitialized: true,
  cookie: { maxAge: 30*60*1000 },
  rolling:true
}))
//注意这里是字符串   容易出错1 
app.set("view engine",'ejs')
//路由封装
var  login=require('./router/login/login.js');

var  admin = require('./router/admin.js');

var  product = require('./router/product/product.js');

//静态文件服务  容易出错2  是express 
app.use(express.static('public'))
//映射upload为虚拟目录,去upload里面寻找图片
app.use('/upload',express.static('upload'))

//必须放在上面 否则不生效  
app.use((req,res,next)=>{
	console.log(req.url);
	let visUrl = req.url;
	//通过session来做  然后login页个访问接口不需要判断
	if(visUrl == "/login/login" || visUrl == "/login/" || visUrl == "/login/doLogin"){
		console.log("visUrl======"+visUrl);
		next();  //不需要校验 
	}else{
		console.log("userinfo="+req.session.userinfo);
		if(req.session.userinfo && req.session.userinfo.username !=''){
			next();
		}else{
			res.redirect('/login/login');
		}
	}
});



//有session 可以直接访问主页 productList  没有就不能访问

//登录前的中间件判断  没有登录就不能进入主页 productList

//express的自定义路由
//admin  全部去寻找admin这个模块里面 再具体定义就好了 
//admin/user  
//admin/pic
app.use('/login',login);

app.use('/admin',admin)

app.use('/product',product)

app.listen("3333",()=>console.log("server  start"));

这里需要做的就是中间件登录前的判断,没有登录过的用户,无法直接进入商品列表list页面哦
同样这里也要再次定义一下静态文件托管中间件static,删除会报错哦

最后大功告成,加油···

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值