express-generator模块

前面介绍了 express 模块的基本应用,在使用 express 模块编写程序时,都是手动编写代码,这在实际开发中比较耗时且效率低,这时可以使用 express-generator 模块。express-generator 模块是 express 的应用生成器,通过该模块,可以快速创建一个 express 应用。本节将对 express-generator 模块的使用进行讲解。

创建项目

express-generator 模块与 express 模块一样,也是第三方模块,因此在使用之前,需要进行安装,命令如下:

npm install express-generator

安装完成以后,就可以使用 express-generator 来创建项目了。步骤如下。

(1) 创建项目。创建项目时,首先需要使用 “cd项目路径” 命令来切换并选择路径,然后使用 “express项目名称” 命令来创建项目。例如,图 14.11 所示为通过 WebStorm 的命令终端在指定路径下创建了一个名称为 my_project 的项目。项目创建完成后,控制台会显示项目的相关命令,如安装项目所需模块、启动项目等命令。

image 2024 04 17 20 11 18 170
Figure 1. 图14.11 创建项目

(2) 打开创建的项目文件夹,可看到自动生成了多个文件和文件夹,它们的作用如图14.12所示。

image 2024 04 17 20 11 51 706
Figure 2. 图14.12 项目文件夹

使用 express-generator 模块创建的项目,默认使用 jade 模板引擎,即第 13 章中的 pug 模板,jade 文件的结构及语法与 pug 文件一致。

(3) 继续在命令终端中输入命令,可以进入项目,并安装相关模块,具体如图 14.13 所示。

image 2024 04 17 20 12 54 401
Figure 3. 图14.13 安装第三方模块

(4) 所有配置完成后,使用命令 “npm start” 启动该项目,如图14.14所示,打开浏览器,输入网址 http://127.0.0.1:3000(初始端口号为 3000),可以看到浏览器运行效果如图 14.15 所示。

image 2024 04 17 20 13 31 818
Figure 4. 图14.14 启动项目
image 2024 04 17 20 13 50 602
Figure 5. 图14.15 浏览器运行效果

从图 14.15 可以看出,该项目是一个完整的、可以运行的项目,只是项目比较简单,接下来我们只需添加项目的主体内容,然后根据需求修改项目的相关配置即可。

设置项目参数

前面学习了如何使用 express-generator 模块创建一个最基本的项目,实际上,在创建项目时,还可以同时设定项目的参数,如模板类型等。在终端对话框中使用 “express --help” 命令,可以查看使用 express-generator 模块创建项目时能够设置的参数,如图 14.16 所示。各参数说明如表 14.8 所示。

image 2024 04 17 20 14 54 650
Figure 6. 图14.16 express-generator模块可以设置的参数
image 2024 04 17 20 15 17 482
Figure 7. 表14.8 express-generator模块可以设置的参数说明

例如,创建一个名称为 project 的项目,并且设置要使用的模板引擎为 ejs,则创建项目的命令如下:

express –e project

express-generator模块应用

本节通过一个实例讲解如何在实际开发中使用 express-generator 模块。

【例14.6】实现网站的登录和退出功能。(实例位置:资源包\源码\14\06)

要实现该项目,首先使用 express-generator 创建项目,项目名称为 login,命令如下:

express login

进入项目并下载项目的相关模块,命令如下。

cd login
npm install

准备工作完成后,接下来完成项目的实际功能,步骤如下。

(1) 配置 app.js 文件。打开 app.js 文件,在该文件中,将项目的模板引擎修改为 ejs,并将 ejs 模板映射至 html 文件,这样就可以直接在项目中访问 html 文件;然后通过中间件对网站的 session 信息进行设置;最后分别使用 app.get() 方法和 app.set() 方法实现设置用户登录状态、用户登录及用户退出的接口。代码如下:

//引入第三方模块
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var logger = require('morgan');
var session = require('express-session');
var FileStore = require('session-file-store')(session);
var bodyParser = require('body-parser');
var cookieParser = require('cookie-parser');

// 引入自定义模块
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
//创建服务器对象
var app = express();

var identityKey = 'skey';
var users = require('./users').items;

var findUser = function(name, password){
  return users.find(function(item){
    return item.name === name && item.password === password;
  });
};


// 对服务器进行设置
app.set('views', path.join(__dirname, 'views'));

var ejs=require("ejs");
app.engine(".html",ejs.__express);
app.set("view engine","html")

//设置中间件
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({
  name: identityKey,
  secret: 'mingrisoft',  // 用来对session id相关的cookie进行签名
  store: new FileStore(),  // 本地存储session(文本文件,也可以选择其他store,比如redis的)
  saveUninitialized: false,  // 是否自动保存未初始化的会话,建议false
  resave: false,  // 是否每次都重新保存会话,建议false
  cookie: {
    maxAge: 1000 * 1000  // 有效期,单位是毫秒
  }
}));



//GET请求,设置用户登录状态
app.get('/', function(req, res, next){
  var sess = req.session;
  var loginUser = sess.loginUser; //记录登录用户
  var isLogined = !!loginUser;    //将登录用户变量转化为对应布尔值

  res.render('index', { //渲染index模板文件,设置登录状态和登录用户
    isLogined: isLogined,
    name: loginUser || ''
  });
});
//POST请求,判断用户是否能够登录成功
app.post('/login', function(req, res, next){
  var sess = req.session;
  var user = findUser(req.body.name, req.body.password);

  if(user){
    req.session.regenerate(function(err) {
      if(err){
        return res.json({ret_code: 2, ret_msg: '登录失败'});
      }
      req.session.loginUser = user.name;
      res.json({ret_code: 0, ret_msg: '登录成功'});
    });
  }else{
    res.json({ret_code: 1, ret_msg: '账号或密码错误'});
  }
});
//GET请求,退出登录时,清空Session
app.get('/logout', function(req, res, next){
  req.session.destroy(function(err) {
    if(err){
      res.json({ret_code: 2, ret_msg: '退出登录失败'});
      return;
    }
    res.clearCookie(identityKey);
    res.redirect('/');
  });
});



// catch 404 and forward to error handler
app.use(function(req, res, next) {
  next(createError(404));
});

// error handler
app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render('error');
});

module.exports = app;

设置网站的 session 信息时,使用了 express-sessionsession-fill-store 模块。其中,express-session 模块用来将会话数据存储在服务器上,默认为内存存储,所以一旦 express 服务器被重启,那么 session 数据将会丢失,而 session-fill-store 模块解决了这个问题,它提供了本地文件的存储,这样,即使服务器重启后,如果用户访问页面,访问的状态还在。因此,express-sessionsession-fill-store 模块通常都一起配合使用。

(2) 定义用户信息。新建一个 user.js 文件,作为虚拟数据库,在该文件中,添加用户名和密码,当用户输入的用户名和密码与该文件中的用户名和密码匹配时,客户端页面中显示当前登录用户。user.js 文件中的代码如下:

module.exports = {
     items: [
          {name: 'mingrisoft', password: '123456'}
     ]
};

(3) 修改客户端页面。由于在 app.js 文件中,页面的模板引擎修改为 ejs,并且直接映射至 html 文件,因此需要将 views 文件夹中默认的 jade 文件的后缀修改为 html。打开修改后的 index.html 文件,在该文件中首先添加用户登录相关的表单元素;然后判断用户登录状态,以确定要显示的 HTML 标签元素;最后为 “登录” 按钮添加单击事件,记录用户输入的用户名和密码,并定义一个函数,判断如果是登录成功状态,则刷新页面。index.html 文件中的代码如下:

<!DOCTYPE html>
<html>
<head>
     <title>会话管理</title>
</head>
<body>
     <h2 style="text-align: center">会话管理</h2>
     <p id="loged">
          当前登录用户:<span style="color:red"><%= name %></span>,<a href="/logout" id="logout">退出登录</a>
     </p>
     <fieldset style="width: 300px;text-align: center;margin: 10px auto;border:1px solid #4caf50" id="unlog">
          <legend style="text-align: left">登录</legend>
          <form method="POST" action="/login">
               <label style="display: block;margin-top: 20px">
                     用户名:<input type="text" id="name" name="name" value=""/>
               </label>
               <label style="display: block;margin: 20px auto">
                     密&nbsp;&nbsp;码:<input type="password" id="password" name="password" value=""/>
               </label>
               <div style="text-align: center;margin-bottom: 10px">
                     <input type="submit" value="登录" id="login" style="background: #cddc39;border:1px solid #ff9800"/>
               </div>
          </form>
     </fieldset>
     <script type="text/javascript" src="/jquery-3.1.0.min.js"></script>
     <script>
          if (isLogined) {
               $("#loged").css("display", "block")
               $("#unlog").css("display", "none")
          }
          else {
               $("#unlog").css("display", "block")
               $("#loged").css("display", "none")
          }
     </script>
     <script type="text/javascript">
          $('#login').click(function (evt) {
               evt.preventDefault();
               $.ajax({
                     url: '/login',
                     type: 'POST',
                     data: {
                          name: $('#name').val(),
                          password: $('#password').val()
                     },
                     success: function (data) {
                          if (data.ret_code === 0) {
                               location.reload();
                          }
                     }
               });
          });
     </script>
</body>
</html>

(4) 打开修改后的 error.html 文件,在该页面中设置错误信息,代码如下:

<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <title>出错了</title>
</head>
<body>
<script>
    document.getElementById("mess").innerHTML=message;
    document.getElementById("err").innerHTML=error;
    document.getElementById("errt").innerHTML=error.stack;
</script>
</body>
</html>

(5) 更改端口号。默认情况下,项目的端口号为 3000,用户可以根据自己的需要更改为其他端口号,更改端口号需要在项目的 bin\www 文件中进行,比如,这里将端口号修改为 52273,代码如下:

/**
 * Get port from environment and store in Express.
 */
var port = normalizePort(process.env.PORT || '52273');
app.set('port', port);

(6) 运行项目。首先在 WebStorm 终端命令对话框或者系统的 “命令提示符” 对话框中启动项目,启动项目时,可以使用命令 “npm start”,也可以进入项目的 bin 文件夹中,使用命令 “node www”,然后打开浏览器,输入网址 http:\\127.0.0.1:52273 ,初始效果如图 14.17 所示。输入用户名与密码,单击 “登录” 按钮,运行效果如图 14.18 所示。

image 2024 04 17 20 24 00 507
Figure 8. 图14.17 客户端输入用户信息
image 2024 04 17 20 24 22 452
Figure 9. 图14.18 显示登录用户