nodejs+express+mongoDB+ejs进行注册登录以及增删查改

1 篇文章 0 订阅
1 篇文章 0 订阅

五一闲来无事,便想起了我第一个项目所用的数据库mongoDB,于是便去复习了一下其用法和操作,写了一个基于express框架,mongoDB数据库的简单项目,下面我将详细的对项目做个总结

项目地址:https://github.com/workerfanhaitao/node-express-mongodb-ejs
感兴趣的可以直接在git上或者pull下来看

项目逻辑主要为
在这里插入图片描述
(前提:这里默认是大家电脑上已经安装了node以及mongoDB数据库的,由于这块资源很多,所以这里就不重复说了)
1.项目搭建
首先进入你常用的文件夹

输入命令 npm install express-generator -g 进行全局安装

随后输入命令 express -e project 生成一个名为project(可自定义)的文件夹

cd project 进入文件夹 随后 npm install 进行依赖的安装

这边必须使用nodemon进行项目的启动(否则启动时会卡住)
npm install nodemon -g 后 将 package.json文件中的启动方式由node改为nodemon
在这里插入图片描述
此时使用npm start便能够成功在localhost:3000端口访问到

打开命令行,使用mongo命令连接上mongoDB服务
首先 use project 创建 project数据库
随后
db.createCollection(‘users’) 创建用户集合
db.createCollection(‘article’) 创建文章集合

2.项目构建
文件结构大致如下

在这里插入图片描述
首先执行 npm install mongodb -S 全局安装mongodb模块
创建model文件夹,并在其中封装连接数据库的方法

// model/index.js
var MongoClient = require('mongodb').MongoClient;

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

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

module.exports = {
  connect
}

在routes文件夹的index文件中将其引入并使用进行数据库连接操作

// routes/index.js
router.get('/', function(req, res) {
  model.connect((db) => {
    db.collection('users').find().toArray((err, docs) => {
      console.log(docs);
    })
  })
});

这样就能取到project数据库users集合中的对象列表了,此时是没有数据的,可以手动插入数据进行测试

启动mongo后 使用db.collection(‘users’).insertOne({‘xxx’: ‘xxxx’})或是使用
MongoDB数据库可视工具手动插入 下载地址:https://robomongo.org/

新建页面前先进行准备工作
根目录views文件夹下新建head.ejs, 将通用头部以及css通用样式引入文件放入其中(需要我的样式文件的话可以去上面的git地址中复制下来,因为样式简单,所以自己写也可)

// head.ejs
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel='stylesheet' href='/stylesheets/style.css' />

随后进行注册页面的构建(ps:以下views文件夹中需要跳转的页面均需在routes.js中引入,如下)

// routes/index.js
router.get('/regist', (req, res) => {
  res.render('regist', {});
})

在根目录views文件夹下新建regist.ejs文件,将head通过ejs语法引入

// regist.ejs
<!DOCTYPE html>
<html lang="en">
<head>
  <title>注册</title>
  <%- include head %>
</head>
<body>
  <div class="container">
    <h1 class="margin-b-20">注册</h1>
    <form action="/users/regist" class="margin-b-40" method="post">
      <input class="margin-b-20" type="text" name="username" value="" placeholder="请输入用户名"><br>
      <input class="margin-b-20" type="password" name="password" value="" placeholder="请输入密码"><br>
      <input class="margin-b-20" type="password" name="password2" value="" placeholder="请确认密码"><br>
      <button class="button button-regist" type="submit">注册</button>
    </form>
    <div>已有账号,<a href="/login">立即登录!</a></div>
  </div>
</body>
</html>

接下来在routes文件夹下新建users.js文件并新增用户注册方法(ps:user.js文件别忘了在app.js中引入哦)

// app.js
var usersRouter = require('./routes/users');
app.use('/users', usersRouter);
// users.js
var express = require('express');
var router = express.Router();
var model = require('../model')

//注册接口
router.post('/regist', (req, res) => {
  let data = {
    username: req.body.username,
    password: req.body.password,
    password2: req.body.password2
  }
  model.connect((db) => {
    db.collection('users').insertOne(data, (err, ret) => {
      if (err) {
        console.log('注册失败');
        res.redirect('/regist')
      } else {
        console.log('注册成功');
        res.redirect('/login');
      }
    })
  })
})

构建登录页面前我们需要引入express-session模块
npm install express-session -S

并在app.js中进行配置登录过期时间,如果登录过期将会触发登录拦截

// app.js

var session = require('express-session');

// session配置
app.use(session({
  secret: 'my project',
  resave: false,
  saveUninitialized: true,
  cookie: {maxAge: 1000 * 60 * 60 *24}  //指定登陆对话的有效时长
}))

//登录拦截
app.get('*', (req, res, next) => {
  var username = req.session.username;
  var path = req.path
  if (path !== '/login' && path !== '/regist') {
    if (!username) {
      res.redirect('/login');
    }
  }
  next();
} )

随后在views文件夹下创建登录页面login.ejs

// login.ejs
<!DOCTYPE html>
<html lang="en">
<head>
  <title>登录</title>
  <%- include head %>
</head>
<body>
  <div class="container">
    <h1 class="margin-b-20">登录</h1>
    <form action="/users/login" class="margin-b-40" method="post">
      <input class="margin-b-20" type="text" name="username" value="" placeholder="请输入用户名"><br>
      <input class="margin-b-20" type="password" name="password" value="" placeholder="请输入密码"><br>
      <button class="button button-login" type="submit">登录</button>
    </form>
  </div>
</body>
</html>

同样在routes/users.js文件中加入登录方法

// routes/users.js
//登录接口
router.post('/login', (req, res) => {
  let data = {
    username: req.body.username,
    password: req.body.password
  }
  console.log(data);
  model.connect((db) => {
    db.collection('users').find(data).toArray((err, docs) => {
      if (err) {
        res.redirect('/login');
        console.log('账号或密码错误');
      } else {
        if (docs.length > 0) {
          //登录成功,进行session会话存储
          req.session.username = data.username;
          res.redirect('/?pageIndex=' + 1);
          console.log('登录成功');
        } else {
          res.redirect('/login');
        }
      }
    })
  })
})

views文件夹下创建bar.ejs通用样式头

// views/bar.ejs
<div class="bar">
  <div>
    <a href="/" class="home">
      <img style="width:100%;height:100%" src="/images/index.jpg" alt="首页">
    </a>
  </div>
  <div style="display: flex;width: auto;justify-content: space-around;">
    <span style="margin-right:20px">您好:<%= username %></span>
    <a style="margin-right:20px;color: white;" href="/write">写文章</a>
    <a style="margin-right:20px;color: white;" href="/users/logout">退出</a>
  </div>
</div>
<style>
.bar {
  display: flex;
  justify-content: space-between;
  color: white;
  background: #00B7FF;
  height: 40px;
  line-height: 40px;
  padding: 10px 20px;
  font-size: 18px;
}

.home {
  display: block;
  width: 40px;
  height: 40px;
}
</style>

将其引入index.ejs文件中

// views/index.ejs
<!DOCTYPE html>
<html>
  <head>
    <title>首页</title>
    <%- include head %>
  </head>
  <body>
    <%- include bar %>
  </body>
</html>

创建写文章页面write.ejs

// views/write.ejs
<!DOCTYPE html>
<html>
  <head>
    <title>写文章</title>
    <%- include head %>
  </head>
  <body>
    <%- include bar %>

    <div class="container">
      <form action="/article/add" method="post">
        <input type="hidden" name="id" value="<%= currentArticle.id %>">
        <input type="hidden" name="pageIndex" value="<%= currentArticle.pageIndex %>">
        <input class="write-title margin-b-20" name="title" type="text" placeholder="请输入文章标题" value="<%= currentArticle.title %>">
        <textarea class="write-content margin-b-20" name="content" rows="20"><%= currentArticle.content %></textarea>
        <% if (currentArticle.id) { %>
          <button class="button margin-b-20 flex" type="submit">更新</button>
        <% } else { %>
          <button class="button margin-b-20 flex" type="submit">发布</button>
        <% } %>
      </form>
    </div>
  </body>
  <style>
    .write-title {
      width: 994px;
    }
    .write-content {
      width: 994px;
      padding: 10px 15px;
    }
  </style>
</html>

处理写文章write页面的路由方法

// routes/index.js
//渲染写文章页面
router.get('/write', (req, res) => {
  let username = req.session.username;
  var id = parseInt(req.query.id);
  var pageIndex = req.query.pageIndex;
  var currentArticle = {
    title: '',
    content: ''
  }
  if (id) {
    model.connect((db) => {
      db.collection('article').findOne({id: id}, (err, docs) => {
        if (err) {
          console.log('文章查找失败');
        } else {
          currentArticle = docs;
          currentArticle['pageIndex'] = pageIndex; 
          res.render('write', {username: username, currentArticle: currentArticle});
        }
      })
    })
  } else {
    res.render('write', {username: username, currentArticle: currentArticle});
  }
})

routes文件夹下新建article.js文件并添加新增文章方法,由于之后有编辑操作,所以先将其一起写入,根据判断条件为跳转时的数据中是否存在id

// routes/article.js
//文章 添加/更新 操作
router.post('/add', (req, res) => {
  var id = parseInt(req.body.id);
  var pageIndex = req.body.pageIndex;
  if (id) {
    var title = req.body.title;
    var content = req.body.content;
    model.connect((db) => {
      db.collection('article').updateOne({id: id}, {$set:{title: title, content: content}}, (err, docs) => {
        if (err) {
          console.log('文章更新失败' + err);
        } else {
          console.log('文章更新成功');
          res.redirect('/?pageIndex=' + pageIndex);
        }
      })
    })
  } else {
    let data = {
      id: Date.now(),
      username: req.session.username,
      title: req.body.title,
      content: req.body.content
    }
    model.connect((db) => {
      db.collection('article').insertOne(data, (err, ret) => {
        if (err) {
          console.log('文章发布失败');
        } else {
          console.log('文章发布成功');
          res.redirect('/');
        }
      })
    })
  }
})

routes文件夹下index.js获取文章列表数据
这里使用了一个新的模块 moment将数字串转换为时间格式
npm install moment -S 并将其引入

// routes/index.js
var moment = require('moment');

router.get('/', function(req, res) {
  let username = req.session.username;
  var data = {
    pageIndex: req.query.pageIndex || 1,
    pageTotal: 0,
    pageSize: 3,
    list: []
  }
  model.connect((db) => {
    db.collection('article').find().toArray((err, docs) => {
      if (err) {
        console.log('获取文章列表失败');
      } else {
        data.pageTotal = Math.ceil(docs.length/data.pageSize);
        //查询当前页的文章列表
        model.connect((db) => {
          db.collection('article').find().sort({_id: -1}).limit(data.pageSize).skip((data.pageIndex-1)*data.pageSize).toArray((err, docs2) => {
            if (err) {
              console.log('获取文章列表分页数据失败');
            } else {
              if (docs2.length === 0) {
                res.redirect('/?pageIndex='+ ((data.pageIndex-1) || 1))
              } else {
                data.list = docs2;
                data.list.map((item) => {
                  item['time'] = moment(item.id).format('YYYY-MM-DD HH:mm:ss');
                })
                res.render('index', { username: username, data: data });
              }
            }
          })
        })
      }
    })
  })
});

index.ejs页面渲染文章列表

// views/index.ejs
<!DOCTYPE html>
<html>
  <head>
    <title>首页</title>
    <%- include head %>
  </head>
  <body>
    <%- include bar %>
    <div class="container">
      <table>
        <tr>
          <th>ID</th>
          <th>作者</th>
          <th>发布时间</th>
          <th>标题</th>
          <th>操作</th>
        </tr>
        <% data.list.map((item, index) => { %>
          <tr>
            <td><%= item._id %></td>
            <td><%= item.username %></td>
            <td><%= item.time %></td>
            <td><a href="/article-detail?id=<%= item.id %>&pageIndex=<%= data.pageIndex %>"><%= item.title %></a></td>
            <td><a style="margin-right:20px" href="/write?id=<%= item.id %>&pageIndex=<%= data.pageIndex %>">编辑</a><a href="/article/delete?id=<%= item.id %>&pageIndex=<%= data.pageIndex %>">删除</a></td>
          </tr>
        <% }) %>
      </table>
      <div class="pages">
        <% for(let i = 1; i <= data.pageTotal; i++) { %>
          <a href="/?pageIndex=<%= i %>"><%= i %></a>
        <% } %>
      </div>
    </div>
  </body>
  <style>
    .pages {
      display: flex;
      justify-content: flex-end;
    }
  </style>
</html>

文章删除
在article.js文件中编辑文章删除方法

// routes/article
//文章删除操作
router.get('/delete', (req, res) => {
  var id = parseInt(req.query.id);
  var pageIndex = req.query.pageIndex;
  model.connect((db) => {
    db.collection('article').deleteOne({id: id}, (err, ret) => {
      if (err) {
        console.log('文章删除失败');
      } else {
        console.log('文章删除成功');
      }
      res.redirect('/?pageIndex=' + pageIndex);
    })
  })
})

至此,此项目注册登录,以及数据的增删查改就已经完成了,不明白或者运行有问题的话可以去clone一下我上传到git上面完整的代码看看,也可以留言,感谢查看

  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
1. 安装依赖 安装`express`、`mongoose`、`body-parser`和`cors`: ``` npm install express mongoose body-parser cors --save ``` 2. 连接数据库 在`app.js`中连接数据库: ```javascript const express = require('express'); const mongoose = require('mongoose'); const bodyParser = require('body-parser'); const cors = require('cors'); const app = express(); // 连接数据库 mongoose.connect('mongodb://localhost/test', { useNewUrlParser: true }); const db = mongoose.connection; db.on('error', console.error.bind(console, '连接错误:')); db.once('open', function() { console.log('连接成功'); }); app.use(bodyParser.json()); app.use(cors()); app.listen(3000, () => console.log('服务器已启动')); ``` 3. 定义模型 在`models`文件夹下创建`user.js`文件,定义用户模型: ```javascript const mongoose = require('mongoose'); const userSchema = new mongoose.Schema({ name: String, age: Number, gender: String, }); const User = mongoose.model('User', userSchema); module.exports = User; ``` 4. 增加数据 在`app.js`中增加路由,实现增加用户功能: ```javascript const express = require('express'); const mongoose = require('mongoose'); const bodyParser = require('body-parser'); const cors = require('cors'); const User = require('./models/user'); const app = express(); // 连接数据库 mongoose.connect('mongodb://localhost/test', { useNewUrlParser: true }); const db = mongoose.connection; db.on('error', console.error.bind(console, '连接错误:')); db.once('open', function() { console.log('连接成功'); }); app.use(bodyParser.json()); app.use(cors()); // 增加用户 app.post('/users', (req, res) => { const user = new User({ name: req.body.name, age: req.body.age, gender: req.body.gender, }); user.save((err, user) => { if (err) { console.error(err); res.sendStatus(500); } else { res.json(user); } }); }); app.listen(3000, () => console.log('服务器已启动')); ``` 5. 查询数据 在`app.js`中增加路由,实现查询用户功能: ```javascript const express = require('express'); const mongoose = require('mongoose'); const bodyParser = require('body-parser'); const cors = require('cors'); const User = require('./models/user'); const app = express(); // 连接数据库 mongoose.connect('mongodb://localhost/test', { useNewUrlParser: true }); const db = mongoose.connection; db.on('error', console.error.bind(console, '连接错误:')); db.once('open', function() { console.log('连接成功'); }); app.use(bodyParser.json()); app.use(cors()); // 增加用户 app.post('/users', (req, res) => { const user = new User({ name: req.body.name, age: req.body.age, gender: req.body.gender, }); user.save((err, user) => { if (err) { console.error(err); res.sendStatus(500); } else { res.json(user); } }); }); // 查询用户 app.get('/users', (req, res) => { User.find((err, users) => { if (err) { console.error(err); res.sendStatus(500); } else { res.json(users); } }); }); app.listen(3000, () => console.log('服务器已启动')); ``` 6. 更新数据 在`app.js`中增加路由,实现更新用户功能: ```javascript const express = require('express'); const mongoose = require('mongoose'); const bodyParser = require('body-parser'); const cors = require('cors'); const User = require('./models/user'); const app = express(); // 连接数据库 mongoose.connect('mongodb://localhost/test', { useNewUrlParser: true }); const db = mongoose.connection; db.on('error', console.error.bind(console, '连接错误:')); db.once('open', function() { console.log('连接成功'); }); app.use(bodyParser.json()); app.use(cors()); // 增加用户 app.post('/users', (req, res) => { const user = new User({ name: req.body.name, age: req.body.age, gender: req.body.gender, }); user.save((err, user) => { if (err) { console.error(err); res.sendStatus(500); } else { res.json(user); } }); }); // 查询用户 app.get('/users', (req, res) => { User.find((err, users) => { if (err) { console.error(err); res.sendStatus(500); } else { res.json(users); } }); }); // 更新用户 app.put('/users/:id', (req, res) => { User.findByIdAndUpdate(req.params.id, { $set: { name: req.body.name, age: req.body.age, gender: req.body.gender, }, }, { new: true }, (err, user) => { if (err) { console.error(err); res.sendStatus(500); } else { res.json(user);

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值