Express脚手架项目

新建一个b文件夹,之后在命令窗口express  -e   pro(项目的名字)搭建脚手架   ----------->cd pro ----------  npm i安装依赖。

之后npm start既可以启动项目。(这里前提是设备中安装过express和node的全局环境哦)

下面主要用脚手架项目产生的文件进行一个分析:

Package.json依赖解释

body-parser             对http请求体进行解析

cookie-parser          对cookie进行解析的

debug                      输出debug信息

ejs javascrip           t模板引擎

morgan                  在控制台上显示request url 信息

serve-favicon         解决默认请求favicon.ico问题

bin文件夹

有一个www的文本文件,主要是对app.js模块的一个接收,通过node让浏览器negative够解析到app.js模块。

app.js 

这个文件里面接收了很多项目用到的依赖,都暴露给了bin下的www。最主要的作用是对路由的一个接收和使用,还有一些页面视图和静态文件资源路径的一些配置。

routers

这个文件夹主要用来写路由,index.js主要用来做视图展示部分的、渲染页面,user.js主要是用来做数据逻辑处理的。最终都会暴露给app.js文件。

view

view文件夹下面放的是视图文件,相当于html页面,但是express用到的是ejs模板引擎。

注释:

  • EJS是一个简单高效的模板语言,通过数据和模板,可以生成HTML标记文本。可以说EJS是一个JavaScript库,EJS可以同时运行在客户端和服务器端,客户端安装直接引入文件即可,服务器端用npm包安装
  • ejs特点

    (1)快速编译和渲染

    (2)简单的模板标签

    (3)自定义标记分隔符

    (4)支持文本包含

    (5)支持浏览器端和服务器端

    (6)模板静态缓存

    (7)支持express视图系统

  • ejs常用标签

    (1)<% %>流程控制标签

    (2)<%= %>输出内容标签(原文输出HTML标签)

    (3)<%- %>输出标签(HTML会被浏览器解析)

    (4)<%# %>注释标签

    (5)% 对标记进行转义

    (6)<%- include(path) %> 引入  path 代表你引入其他模板的路径

    Eg:<%- include('head.ejs') %>

public

此文件夹下放的是静态资源文件,想js文件,图片,css文件都放在该目录下面,由于app.js对其路径进行了相关配置,所以,如果在ejs文件里面调用,直接写根目录下的路径就可以,不用../public/stylesheet等这样的写,直接/stylesheet下面的文件就可以。

下面利用这个脚手架实现一个简单的登录注册功能

首先,得在view页面建立login.js和register.js文件,此处将数据提交功能也奉上,ajax会将数据传给路由,让路由处理。

<!DOCTYPE html>
<html>
  <head>
    <title>登录</title>
    <link rel='stylesheet' href='/stylesheets/bootstrap.min.css' />
    <script src="/javascripts/jquery-1.11.0.js" type="text/javascript" charset="utf-8"></script>
  </head>
  <body>
  	<%- include('head.ejs')%>
  	<h2>登录</h2>
    <div class="form-group">
	    <label for="user">用户名</label>
	    <input type="text" class="form-control" id="user" placeholder="用户名">
	  </div>
	  <div class="form-group">
	    <label for="password">密码</label>
	    <input type="password" class="form-control" id="password" placeholder="密码">
	  </div>
	  <button type="button" class="btn btn-info" id="login">登录</button>
  </body>
  <script type="text/javascript">
  	 $("#login").click(function(){
  	 	  $.ajax({
  	 	  	type:"post",
  	 	  	url:"/users/login",
  	 	  	data:{name:$("#user").val(),pass:$("#password").val()},
  	 	  	success:function(data){
  	 	  		 if(data==1){
  	 	  		 	 alert("登录成功");
  	 	  		 	 location.href="/"
  	 	  		 }else{
  	 	  		 	alert("登录失败")
                                        location.href="/register"
  	 	  		 }
  	 	  	}
  	 	  });
  	 	
  	 })
  </script>
</html>
<!DOCTYPE html>
<html>
  <head>
    <title>注册</title>
    <link rel='stylesheet' href='/stylesheets/bootstrap.min.css' />
    <script src="/javascripts/jquery-1.11.0.js" type="text/javascript" charset="utf-8"></script>
  </head>
  <body>
  	<%- include('head.ejs')%>
  	<h2>注册</h2>
    <div class="form-group">
	    <label for="user">用户名</label>
	    <input type="text" class="form-control" id="user" placeholder="用户名">
	  </div>
	  <div class="form-group">
	    <label for="password">密码</label>
	    <input type="password" class="form-control" id="password" placeholder="密码">
	  </div>
	  <button type="button" class="btn btn-danger" id="register">注册</button>
  </body>
  <script type="text/javascript">
  	$("#register").click(function(){
  	 	  $.ajax({
  	 	  	type:"post",
  	 	  	url:"/users/register",
  	 	  	data:{name:$("#user").val(),pass:$("#password").val()},
  	 	  	success:function(data){
  	 	  		 if(data!=1){
  	 	  		 	 alert("注册成功");
  	 	  		 	 location.href="/login"
  	 	  		 }else{
  	 	  		 	alert("账户已存在,注册失败")
  	 	  		 }
  	 	  	}
  	 	  });
  	 	
  	 })
  </script>
</html>

这两个文件都差不多,功能实现也差不多。但是想跳转进入这两个页面就需要在首页去执行了,下面是index.ejs的代码

<!DOCTYPE html>
<html>
  <head>
    <title><%= title %></title>
    <link rel="stylesheet" type="text/css" href="/stylesheets/style.css"/>
    <link rel='stylesheet' href='/stylesheets/bootstrap.min.css' />
  </head>
  <body>
    <%- include('head.ejs')%>
    
    <button type="button" class="btn btn-info" onclick="location.href='/login'">登录</button>
    <button type="button" class="btn btn-danger" onclick="location.href='/register'">注册</button>
    
  </body>
</html>

这里引了一个公共头部head.ejs,不过还没有传值。可以尝试一下取不同值在不同页面。另外,点击的时候用location.href这个属性实现页面的跳转,路由需要再index.js里面去配置一下,不然找不到。head.ejs文件如下(后期可以实现一个留言板功能,所以此处头部写成留言板):

<!DOCTYPE html>
<html>
  <head>
    <title></title>
    <style type="text/css">
    	.tit{
    		height: 40px;
    		width: 100%;
    		line-height: 40px;
    		text-align: center;
    		background: orange;
    		font-size: 20px;
    	}
    </style>
  </head>
  <body>
  	
    <h1 class="tit">留言板</h1>

  </body>
</html>

前端工作做完了,接下来就是路由的配置,后台和数据库的处理了,记得安装mongodb依赖(npm i mongodb@2 -D).代码放上

//users.js
var express = require('express');
var router = express.Router();
//var bodyParser = require("body-parser")
var  mongodb = require('mongodb').MongoClient;
var db_str = 'mongodb://localhost:27017/html5';


/* GET users listing. */
router.get('/', function(req, res, next) {
  res.send('respond with a resource');
});

//登录
router.post("/login",(req,res)=>{
//	 console.log(req.body)
	
	mongodb.connect(db_str,(err,database)=>{
		database.collection("user",(err,coll)=>{
			coll.find(req.body).toArray((err,data)=>{
//				console.log(data)
				if(data.length>0){
					res.send("1");
//					res.end()  //express框架里面自己有配置响应结束,不需要再写一遍
                                        database.close();
				}else{
					res.send("2");
                                        database.close();
				}	
			})
		})
		
	})
	
})

//注册
router.post("/register",(req,res)=>{
//	 console.log(req.body)

	mongodb.connect(db_str,(err,database)=>{
	    database.collection("user",(err,coll)=>{
//			coll.find(req.body).toArray((err,data)=>{ //不用找全部信息,只比对用户名即可
	    //find的是对象,会得到许多不需要的信息,通过toArray转换成标准的数组,只取需要的信息
	        coll.find({name:req.body.name}).toArray((err,data)=>{
		        if(data.length>0){
					//账户数据库已存在
					res.send("1");
                                        database.close();
				}else{
						coll.insert(req.body,()=>{
							res.send("2");
	          	                                database.close();
						})
				}	
			})
		})	
	})
})


module.exports = router;

users.js是对前端post提交的数据进行处理。注册时,如果数据库有提交来的数据就注册失败,向前端返回1表示注册失败;没有就向前端返回2表示注册成功,并向数据库添加注册信息。登录时,查找数据库,有相关信息并写对就登录成功,否则登录失败。

当然,还需要在index.js路由上面去配置前端路由,实现页面的跳转。在routers文件夹下的index.js里面,主要是将后台处理好的数据从这儿取到,然后前端通过get请求可以得到,他主要也是渲染前端页面的,处理的是get请求。

//index.js
var express = require('express');
var router = express.Router();

/* GET home page. */
router.get('/', function(req, res, next) {
  res.render('index', { title: 'Express' });
});
router.get('/login', function(req, res){
  res.render('login', {});
});
router.get('/register', function(req, res){
  res.render('register', {});
});

module.exports = router;

上面代码中{}是返回给前端的参数信息,没有就可以不用传。以上就实现了一个express简单的登录注册。

下面就是借助这个登录注册实现一个留言板的功能:

首先,实现的是登录成功之后要将用户名存储一下,给到登录首页,没有登录时候就展示默认页面。此处用到的是session。客户端浏览器访问服务器时,服务器把客户端信息以某种形式记录在服务器上,这就是session。客户端浏览器再次访问只需要从该session中查找该用户的状态就可以了。将session应用到本项目中,就先安装一下全局环境(npm i express-session -g)和依赖(npm i express-session -D),再去配置一下app.js-----主要是引入express-session模块,以及在本项目中去使用一下这个模块。相关配置在app.js中,如下:

var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
//导入该模块
var session = require('express-session');

var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');

var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');

app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
//使用配置,一定要写在路由挂载之前
app.use(session({ 
	secret: 'recommend 128 bytes random string', 
	cookie: { maxAge: 20 * 60 * 1000 },
	resave: true,
	saveUnintialized: true
}))


app.use('/', indexRouter);
app.use('/users', usersRouter);
app.use(function(req, res, next) {
  next(createError(404));
});
app.use(function(err, req, res, next) {
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};
  res.status(err.status || 500);
  res.render('error');
});

module.exports = app;

下面就可以去用了,在登录成功之后,后端路由(users.js)将用户名从数据库中取到,存在req.session.name中。

//users.js里面

//登录
router.post("/login",(req,res)=>{	
	mongodb.connect(db_str,(err,database)=>{
		database.collection("user",(err,coll)=>{
			coll.find(req.body).toArray((err,data)=>{
				if(data.length>0){
                                //存session里面
					req.session.name = data[0].name;
					res.send("1");
                                        database.close();
				}else{
					res.send("2");
                                        database.close();
				}	
			})
		})
		
	})
	
})

在index.js将这个req.session.name传给前端页面,稍微改一下路由参数。

router.get('/', function(req, res, next) {
  res.render('index', {title:'Express',name:req.session.name});
});

然后前面可以得到这个name,对它做一个处理。要求是没有登录的时候(就没有存session),返回的是登录注册信息,当登录成功之后,就是欢迎用户名,然后有两个按钮,一个是注销,一个是留言。

 //index.ejs

<%- include('head.ejs')%>
    
    
    <% if(name){%>
    	
    		<h1>欢迎您:<%- name%></h1>
    		<button type="button" class="btn btn-danger" onclick="location.href='/relogin'">注销</button>
    		<button type="button" class="btn btn-primary" onclick="location.href='/liuyan'">留言</button>
    <% }else{%>
    		<button type="button" class="btn btn-info" onclick="location.href='/login'">登录</button>
				<button type="button" class="btn btn-danger" onclick="location.href='/register'">注册</button>	
    <% }%>

先看注销,注销的话,销毁session

//index.js
router.get('/relogin', function(req, res){
  req.session.destroy((err,data)=>{
  	if(err){
  		console.log(err)
  	}else{
  		res.redirect("/")
  	}
  })
});

注销session有两种写法,一种是req.session.username = undefined;第二种就是上面用到的,即req.session.destroy(function(err){  if(err){  console.log(err)  }else{   res.redirect("/")   } ,常用的是后面这种。其中, res.redirect("/") 是路由的重定向。

再看留言部分,需要建立一个liuyan.ejs页面在view里面,此处将留言数据也提交给了后台,并且从后台拿到了处理之后的数据做一个展示写在table里面。

//liuyan.ejs
<!DOCTYPE html>
<html>
  <head>
    <title>留言</title>
    <link rel='stylesheet' href='/stylesheets/bootstrap.min.css' />
    <script src="/javascripts/jquery-1.11.0.js" type="text/javascript" charset="utf-8"></script>
  </head>
  <body>
  	<%- include('head.ejs')%>
  	<h2>留言</h2>
    <div class="form-group">
	    <label for="title">标题</label>
	    <input type="text" class="form-control" id="title" placeholder="标题">
	  </div>
	  <div class="form-group">
	    <label for="con">内容</label>
	    <input type="text" class="form-control" id="con" placeholder="内容">
	  </div>
	  <button type="button" class="btn btn-info" id="liuyan">发布留言</button>
	  <br />
	  <br />
	  <table class="table table-striped">
	  	<tr><th>序号</th><th>标题</th><th>内容</th></tr>
	  	<% list.map(function(item,i){%>
	  			<tr>
	  				<td><%- i%></td>
	  				<td><%- item.title%></td>
	  				<td><%- item.con%></td>
	  			</tr>
	  	<%})%>
	  	
	  </table>	  
  </body>
  <script type="text/javascript">
  	 $("#liuyan").click(function(){
	 	  $.ajax({
	 	  	type:"post",
	 	  	url:"/users/liuyan",
	 	  	data:{title:$("#title").val(),con:$("#con").val()},
	 	  	success:function(data){
	 	  		 if(data==1){
	 	  		 	 alert("留言成功"); 
	 	  		 	 location.href = "/liuyan"
	 	  		 }else{
	 	  		 	alert("留言失败")
	 	  		 }
	 	  	}
	 	  });
  	 	
  	 })
  </script>
</html>

 提交给了users路由,在/liuyan这个中间件里面做了一个数据的存储。

//users.js
//留言
router.post("/liuyan",(req,res)=>{
//		console.log(req.body)
		mongodb.connect(db_str,(err,database)=>{
			database.collection("liuyan",(err,coll)=>{
		    coll.insert(req.body,(err,data)=>{
		    		res.send("1");
		    		database.close();
		    })	
			})	
		})
})

现在需要从数据库去取到数据,然后展示在前端页面,通过index.js路由来做,在index.js前端路由里面取到存在数据库里的数据做相应处理,然后传给前端页面。前端页面遍历传来的数据展示,在上面liuyan.ejs已处理,可以正常展示。

//index.js
//及得引入数据库
var mongodb = require("mongodb").MongoClient;
var db_str = "mongodb://localhost:27017/html5";

router.get("/liuyan",(req,res)=>{
	mongodb.connect(db_str,(err,database)=>{
		database.collection("liuyan",(err,coll)=>{
           //从数据库中找到倒叙排列
			coll.find({}).sort({_id:-1}).toArray((err,data)=>{
                    //在渲染前端页面时候将取到的数据通过传参的方式传给前端页面
					res.render("liuyan",{list:data})
			})
		})
	})
})

猜你喜欢

转载自blog.csdn.net/keep789/article/details/81514230