expree项目改造 + 数据库操作(CURD)
技术栈
- express
- Node
- ejs
- MongoDB
- CommonJS
- restful api
- Promise + async 函数
实现(增删改查)
-
首先通过npm express -e +项目名 生成一个ejs模板包 通过npm init 项目初始化 npm install(也可简写 npm i)安装依赖
-
进行路由接口的编写 app.js进行路由接口引入 以及中间件的调用
-
细化模块功能 将传进接口数据通过引入控制器模块 函数传参给控制器模块 控制器只负责完成逻辑控制代码 不负责处理数据 所以在控制器模块中引入Model模块 控制器模块通过函数传参给Model模块
-
在Model模块中要进行数据的处理 将数据传入数据库 故要实现与数据库的连接
-
创建单独的db文件夹 数据库的操作分为 定义骨架 创建模型 实例化 考虑到对多个骨架和模型的管理 创建单独的Schema 和Model文件夹 ,分别都建立一个index.js来统一管理schema 和model,在子骨架模块和子模型模块中暴露模块 ,主模块引入, 创建connect.js来连接数据库,需要导入mongoose模块 ,在index.js引入连接模块 ,创建骨架和模型 并实例化实体
-
通过在db下面的index.js 通过return出Promise 在Model模块中通过async和await来判断是否将数据增加/修改/删除/查询成功
数据库的增删改查
//增加 //数据库连接index.js const db={ position:{ add(data){ return new Promise((resolve,reject)=>{ const position = new position_model(data)//position是实体 通过创建一个模型 来实例化一个实体 position.save(err->{ if(err){ resolve(0) }else{ resolve(1); console.log('存储成功') } }) }) } } } //Model模块 const positionModel = { async add({res,positionName,city,companyName}){ const result = await db.position.add({positionName,city,companyName}) //判断是否存储成功 if(result ===1){ res.render('position.ejs',{ data:JSON.parse({ ret:true, info:'添加成功', status:1 }) } }else{ res.render('position.ejs',{ data:JSON.parse({ ret:true, info:'添加失败', status:0 }) } } } }
//删除 const db{ position{ del(data){ return new Promise((resolve,reject)=>{ position_model.find(data,(error,docs)=>{ //找到匹配的数据 删除 if(!(docs.length===0)){ position_model.findById(docs[0]._id,(err,result)=>{ if(result){ //可以删除 resolve(1); result.remove() }else{ //没必要删除 已经删除了 resolve(2) } }) }else{ resolve(0)//未找到匹配的 } }) }) } } } //Model模块 async del ({ res,positionName,city,companyName }){ const result = await db.position.del({ res,positionName,city,companyName }) switch(result){ case 0 : res.render('position',{ data: JSON.stringify({ ret: true, info: '数据库没有这条数据', status: 0 }) }) break; case 1: res.render('position',{ data: JSON.stringify({ ret: true, info: '数据删除成功, status: 1 }) }) break; case 2 : res.render('position',{ data: JSON.stringify({ ret: true, info: '重复删除', status: 2 }) }) break; } }
//修改 const db{ position{ updated(data){ return new Promise((resolve,reject)=>{ position_model.find(data,(error,docs)=>{ if(!(docs.length===0)){ position_model.findById(docs[0]._id,(error,result)=>{ result.city= '北京', result.save(error=>{ if(error){ resolve(0) }else{ resolve(1) } }) }) } }) }) } } } //Model模块 const positionModel={ async updated({{ res,positionName,city,companyName}}){ const result = await db.position.update({positionName,city,companyName}) if( result === 0 ){ res.render('position',{ data: JSON.stringify({ ret: true, status: 0, info: '修改失败' }) }) }else{ res.render('position',{ data: JSON.stringify({ ret: true, status: 1, info: '修改成功' }) }) } } }
//查询query const db{ position{ query(data){ return new Promise((resolve,reject)=>{ if(data){ position_model.find(data,(error,docs)=>{ resolve(docs) }) }else{ position_model.find({},(error,docs)=>{ resolve(docs) }) } }) } } } //Model模块 const positionModel = { async query({ res,positionName,city,companyName }){ const result = await db.position.query({ res,positionName,city,companyName }) res.render('position.ejs',{ data:JSON.parse({ ret:true, info:'查询结果', data:result }) }) } }
使用token实现身份验证
-
安装openssl 安装完成设置环境变量 (需重启电脑)
-
前端通过ajax发送表单数据 前端判断有无token,在onload事件下判断,若存在token ,则保持用户的登陆信息,直接跳转首页 若不存在token 提醒用户登陆
-
token需要后端安装插件jsonwebtoken 并通过openssl生成私钥和公钥 通过文件系统来读取私钥 通过负载(数据)和私钥及算法来生成token,将生成的token给前端
-
前端判断ajax返回的数据 利用cookie将token本地存储
//创建文件夹用来生成私钥和公钥 // 产生私钥 openssl genrsa -out ./private_key.pem 1024 1024 代表私钥长度 // 产生公钥 openssl rsa -in ./private_key.pem -pubout -out ./public_key.pem let private_key = fs.readFileSync(path.join(__dirname),'存私钥的文件路径') //var auto_token = jwt.sign(palyload, private_key,{ algorithm: 'RS256'}); //palyload 代表负载(数据) RS256表示算法
var auto_token = jwt.sign(username, private_key,{ algorithm: ‘RS256’});
```javascript //login.html function web_load(){ var token = $.cookie('token') if(token){ location.href = './index.html' }else{ alert('please login') } }//在body中 onload="web_load()" $('.login').on('click',function(){ $.ajax({ url:'', amethod:'POST', data:{ username: password: token:$.cookie('') }, success(res){ var result = JSON.parse(res) if(result.status===1){ $.cookie('') } } }) })
//路由模块login const express = require('express') const router = express.Route() const fs = require('fs') const path = require('path') const jwt = require('jsonwebtoken') router.route('') .post((req,res,next)=>{ const {token,username,password}=req.body if(token){ res.render('login.ejs',{ data:JSON.stringify({ ret:true, status:1 }) }) }else{ //不存在token 生成token //然后返回给前端 res.render('login.ejs',{ data:JSON.stringify({ status:1, token: }) }) } })
自动化测试 mocha
- 是现在比较流行的JavaScript测试框架之一,可以运行在Node环境和浏览器环境
- 测试框架:可以运行测试的工具,可以为JavaScript应用添加测试,保证代码质量
- 测试异步代码
- 基本语法:assert断言
- 断言库:chai
- should风格断言
- expect风格断言
-