express结合ejs模板-登录页面

Express 是一个简洁而灵活的 node.js Web应用框架, 安装cnpm install -g express,利用epress -e XXX 可以简单的生成express模板。

生成的模板项目如下:

其中:

bin/www ,执行node ./bin/www作用是启动web应用,包括生成web server、监听端口等。

app.js 暴露app模块并在bin/www中require,其作用是指定路由、http拦截器、session、cookie等。

public 存放外部资源,包括图片 ,css文件,引入的js模块等

routes文件夹存放路由信息,所谓路由,可以认为是http拦截器。作用包括: (1)拦截浏览器地址栏的url并指定文件渲染; (2) 拦截前端页面请求并处理、返回数据和页面。

views 文件夹存储ejs模板的前端页面。ejs类似jsx,一般是将数据嵌入到ejs模板中并编译,可以利用jquery等实现渲染和数据请求的异步。

在express中,服务器res可直接调用render函数渲染ejs文件,并传入数据。

登录/注册服务

以登录/注册服务为例,首先需要在views文件夹下写需要的ejs页面,如

login.ejs

<!DOCTYPE html>
<html>
  <head>
    <title>登录</title>
    <%- include head %>
  </head>
  <body>
    <div class="form-box">
        <form action="/users/login" method="post">
            <input type="text" name="username" value="" placeholder="请输入用户名">
            <input type="password" name="password" value="" placeholder="请输入密码">
            <input type="submit" name="" value="登录">
        </form>
        <div>没有帐号 <a href="/regist">立即注册</a></div>
    </div>
  </body>
</html>

regist.ejs

<!DOCTYPE html>
<html>
  <head>
    <title>注册</title>
    <%- include head %>
  </head>
  <body>
    <div class="form-box">
        <form action="/users/regist" method="post">
            <input type="text" name="username" value="" placeholder="请输入用户名">
            <input type="password" name="password" value="" placeholder="请输入密码">
            <input type="password" name="password2" value="" placeholder="请确认密码">
            <input type="submit" name="" value="注册">
        </form>
        <div>已有帐号 <a href="/login">立即登录</a></div>
    </div>
  </body>
</html>

然后,在routes下注册相关路由

routes/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('/regist', function(req, res, next) {
  res.render('regist', {})
})

// 渲染登录页
router.get('/login', function(req, res, next) {
  res.render('login', {})
})

module.exports = router;

指定地址栏输入/,/regist,/login分别渲染对应的index,regist,login页面并返回页面。

routers/users.js

var express = require('express');
const model = require('../model');
var router = express.Router();

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

// 注册接口
router.post('/regist', function(req, res, next){
  var data = {
    username: req.body.username,
    password: req.body.password,
    password2: req.body.password2
  }
  // 插入数据库之前需要验证数据...
  model.connect(function(db) {
    db.collection('users').insertOne(data, function(err,ret){
      if (err){
        console.log('注册失败')
        res.redirect('/regist')
      }else{
        res.redirect('/login')
      }
    })
  })
})

router.post('/login', function(req, res, next) {
  var data = {
    username: req.body.username,
    password: req.body.password
  }
  // 需要有数据校验
  model.connect(function(db) {
    db.collection('users').find(data).toArray(function(err, docs){ // doc 查询结果
      if (err || docs.length <= 0){
        res.redirect('/login')
      }else{
        // 登录成功
        req.session.username = data.username // 保存到session
        res.redirect('/')
        
      }
    })
  })
})
module.exports = router;

当页面表单提交数据时,调用相应的/users/login,users/regist处理、提交数据库并返回。

最后:封装数据库

var MongoClient = require('mongodb')

const url = 'mongodb://localhost:27017'
var dbName = 'project'

// 封装数据库连接方法
function connect(callback) {
    MongoClient.connect(url, function(err, client) {
        if (err){
            console.log('数据库连接错误')
        }else{
            var db = client.db(dbName)
            callback && callback(db)
            client.close()
        }
    })
}

module.exports = {
    connect
}

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')));

// session的配置
app.use(session({
  secret: 'qf project',
  resave: false,
  saveUninitialized: true,
  cookie: {maxAge: 1000 * 60 * 5}
}))

// 使用路由
app.use('/', indexRouter);
app.use('/users', usersRouter);

// 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;

public/stylesheets/style.css css样式

body {
  padding: 50px;
  font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;
}

a {
  color: #00B7FF;
}

.form-box {
  width: 300px;
  margin: 0 auto;
  margin-top: 100px;
}
.form-box form>input {
  display: block;
  height: 100%;
  width: 100%;
  height: 50px;
  line-height: 50px;
  border: 1px #d9d9d9 solid;
  border-radius: 5px;
  font-size: 14px;
  -webkit-transition: all .3s ease-out;
  transition: all .3s ease-out;
  margin-bottom: 20px;
  overflow: hidden;
  box-sizing: border-box;
}
.form-box form>input[type='text'], .form-box form>input[type='password'] {
  padding: 0 10px;
}
.form-box form>input[type='submit'] {
  font-size: 16px;
  border: 0;
  background-color: #03a9f4;
  color: #fff;
  cursor: pointer;
}
.form-box>div {
  text-align: center;
  line-height: 50px;
}

演示

编辑于 2020-07-23 16:46