Node.js Koa2 MongoDB Redis egg.js

简介: Node.js Koa2 MongoDB Redis egg.js

基于Chrome V8引擎的JavaScript运行时

  • V8是chrome的js引擎,以速度著称
  • 运行时:代码的运行环境
  • 之前只有浏览器能运行js

    安装node

  • nodejs.cn
  • msi
  • node -v

    npm

  • node package manage nodejs软件包管理工具
  • npmjs.com
  • 会随着nodejs一起被安装
  • npm init 生成package.json其中包括项目所有依赖

    nodemon

  • 当检测到目录中的文件更改时,它会自动重启node应用程序。
  • npm i nodemon --save-dev
  • 使用了nodemon 就可以使用npm run dev ,只有node,使用node xx.js

    common.js ES6模块化

    注意导出用{},导入也要用{}接收
    image.png

image.png

image.png

image.png

const sum =required(./地址)//多个用大括号
module.exports={
   
   sum,text}

区别

image.png

image.png

image.png这个会报错,ES Module必须放在最外层

nodejs debug

image.png

image.png

image.png

image.png

node处理http

image.png

image.png

image.png

image.png

image.png

Get请求

  • 引入queryString
  • queryString.parse(str)产生一个包含键值对的对象

    Post请求体通过流的形式

    Koa2 框架

  • 安装脚手架 npm i -g koa-generator //-g全局安装
  • 查看是否安装成功 koa2 --version
  • cd到文件夹在命令行输入koa2
  • 在命令行输入npm i / npm run start
  • 访问http://localhost:3000/
  • app.use(...)里都是中间件
  • 每个中间件都是async函数

    写一个接口(动态参数)

  • 在routes文件夹下新建js文件
const router = require('koa-router')()
router,prefix('/api')
router.get('/json', async (ctx) => {
   
   
  ctx.body = 'api list'
})
//ctx是res,rep的集合。ctx.query可以获取到queryString/ctx.request.body获取请求体
router.get('/:id',loginCheck,async function (ctx,next){
   
   
const id = ctx.params.id
const address = await getAddressById(id)
ctx.body = new SuccessModel(address)
})
module.exports = router
//数据库里tabs:[all,a,b,c] in里面的内容表示tabs属性要包含all
const list =await Product.find({
   
   shopId,tabs:{
   
   
 $in:all
}}).sort( _id:-1)
//数据库里_id是一个字符串,in里是一个数组,表示_id在这个ids数组中就能被找到
const list =await Product.find({
   
   shopId,_id:{
   
   
 $in:ids
}})
  • 在app.js里引入,注册
const index = require('./routes/index')
app.use(index.routes(), index.allowedMethods())

svg验证码

svg-captcha

 ctx.body = svgCaptcha.create({
   
   
    size:5,
    ignoreChars:'0olil',
    color:true,
    noise:3
  }).data

邮箱nodemailer

npm i nodemailer -S
配置文件

module.exports = {
   
   
    host: 'smtp.qq.com',
    port: 465,
    secure: true,
    auth: {
   
   
      user: '2252647301@qq.com',
      pass: 'aptwbjjnhvlqdjjg'
    }
  };

在route里引入使用

const nodemailer = require('nodemailer');
const config = require('../mailconfig.js');

router.get('/string', async (ctx, next) => {
   
   
  const mailOptions = {
   
   
    from: '2252647301@qq.com',
    to: '2252647301@qq.com',
    subject: 'Test email',
    text: 'This is a test email',
    html: `<title>HTML email</title>`
  };
  const transporter = nodemailer.createTransport(config);
  try {
   
   
    const info = await transporter.sendMail(mailOptions);
    console.log('Email sent: ' + info.response);
    ctx.body = {
   
    success: true };
  } catch (error) {
   
   
    console.log(error);
    ctx.body = {
   
    success: false };
  }
})
后续要封装成方法

密码加密

//封装成一个加密方法
const crypto=require('crypto')
module.exports = str=> crypto.createHash('md5').update(str).digest('hex')

  password: {
   
   
        type:String,
        required:true,
        set:value=>md5(value),
        select:false//以后都不会返回密码
    }//这样存入数据库的技术加密后的密码

中间件

app.use(async (ctx, next) => {
   
   
  const start = new Date()
  await next()//只有await执行完之后才能执行之后的代码,next()表示执行下一个中间件
  const ms = new Date() - start
  console.log(`${
     
     ctx.method} ${
     
     ctx.url} - ${
     
     ms}ms`)
})
//多个中间件(p1,p2),按顺序执行next之前的代码,之后回过头来执行p2里next后的方法,p1里的next之后的方法

MongoDB

  • mongodb.com production 社区服务 msi
  • 接受条框后点Custom
  • 不要勾选MongoDB compass
  • 如果失败重新安装
  • 如果弹出错误忽略

image.png

  • 查看安装的MongoDB文件夹是是否有data log文件夹没有就新建,在data里新建db文件夹,在log里新建mongod.log
  • 在bin文件夹下打开控制台输入启动mongo//mongodb.exe可关,mongod.exe不能关

image.png

  • 图形界面,在官网sofeware下载compass 打开点击connect
  • 如果连接失败,把data里的db里的mongod.lock删除,重新启动

    使用compass

    collect约等于表,document约等于表里的一项数据
  • create database
  • create collection
  • 查询

image.png

  • 排序 1正序 -1逆序

image.png

MongoDB连接nodejs

  • 安装npm i mongodb --save
// nodejs 连接 mongodb
// 体会 nodejs 连接 mongodb 的能力,不会真正的用到路由上
// mongoose 对接路由的功能

const MongoClient = require('mongodb').MongoClient

const url = 'mongodb://localhost:27017' // 本地启动的 mongodb 服务
const dbName = 'comment1' // 数据库(留言板项目的数据库 )

MongoClient.connect(url, {
   
   
    useUnifiedTopology: true,
    useNewUrlParser: true
}, (err, client) => {
   
   
    if (err) {
   
   
        console.error('mongodb 连接出错', err)
        return
    }
    console.log('mongodb 连接成功')

    // 切换数据库 database
    const db = client.db(dbName)

    // 切换到指定的集合 collection
    const userCollection = db.collection('users')

    // // 查询数据
    // userCollection.find().sort({ _id: -1 }).toArray((err, result) => {
   
   
    //     if (err) {
   
   
    //         console.error('查询数据出错', err)
    //         return
    //     }
    //     console.log('查询结果', result)
    // })

    // // 新增数据
    // userCollection.insertOne({
   
   
    //     username: 'shuangyue',
    //     password: 'abc',
    //     age: 30,
    //     city: 'beijing'
    // }, (err, result) => {
   
   
    //     if (err) {
   
   
    //         console.error('插入数据出错', err)
    //         return
    //     }
    //     console.log('插入后的返回结果', result.insertedCount, result.insertedId)//插入数量,插入的数据id
    // })

    // // 修改数据
    // userCollection.updateOne(
    //     { username: 'zhangsan' }, // 修改的条件
    //     { $set: { age: 21 , city: 'beijing'} }, // 修改的内容
    //     (err, result) => {
   
   
    //         if (err) {
   
   
    //             console.error('修改数据出错', err)
    //             return
    //         }
    //         console.log('修改后的返回结果', result.modifiedCount)
    //     }
    // )

    // 删除数据
    userCollection.deleteOne({
   
    username: 'wangwu' }, (err, result) => {
   
   
        if (err) {
   
   
            console.error('删除数据出错', err)
            return
        }
        console.log('删除成功')
    })

    // 关闭
    // client.close()
})

规范连接 mongoose

image.png

  • 在文件夹路径上唤出控制台,输入npm i mongoose --save
  • 新建文件夹,新建js文件
  • 一定要先启动mongod.exe

image.png

image.png
db.js

// 连接数据库(mongodb 的服务端)

const mongoose = require('mongoose')

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

mongoose.set('useCreateIndex', true)
mongoose.set('useFindAndModify', true)

// 开始连接
mongoose.connect(`${
     
     url}/${
     
     dbName}`, {
   
   
    useNewUrlParser: true,
    useUnifiedTopology: true
})

const conn = mongoose.connection

conn.on('error', err => {
   
   
    console.error('mongoose 连接出错', err)
})

module.exports = mongoose

创建schema,定义了model会自动创建collection加一个s
model.js

// 数据模型(规范数据格式)

const mongoose = require('./db')

// 定义 User Schema (数据规范)
const UserSchema = mongoose.Schema({
   
   
    username: {
   
   
        type: String,
        required: true, // 必需
        unique: true // 唯一,不重复
    },
    password: String,
    age: Number,
    city: String,
    // 性别
    gender: {
   
   
        type: Number,
        default: 0 // 0 - 保密,1 男,2 女
    }
}, {
   
   
    timestamps: true // 时间戳,自动添加文档的创建时间、更新时间
})

// 定义 User Model
const User = mongoose.model('user', UserSchema)

// 定义 Comment Schema
const CommentSchema = mongoose.Schema({
   
   
    content: {
   
   
        type: String,
        required: true // 必需
    },
    username: String // 用户名
}, {
   
    timestamps: true })

// 定义 Comment Model
const Comment = mongoose.model('comment', CommentSchema)

module.exports = {
   
   
    User,
    Comment
}

新建文件夹查询新增

// 使用 model 操作数据

const {
   
    User } = require('./model')

// 定义一个 async 的匿名函数,并执行。为了里面能用 await
!(async () => {
   
   
    // // 新增数据 - 1
    // const zhangsan = new User({
   
   
    //     username: 'zhangsan',
    //     password: 'abc',
    //     age: 20,
    //     city: 'beijing',
    //     gender: 1
    // })
    // zhangsan.save()

    // // 新增数据 - 2
    // const lisi = await User.create({
   
   
    //     username: 'lisi',
    //     password: '123',
    //     age: 23,
    //     city: 'shanghai'
    // })
    // console.log('lisi 创建完成', lisi)

    // // 查询列表数据,返回的是数组
    // const userList = await User.find({ username: 'zhangsan' })
    // const userList = await User.find().sort({ _id: -1 })
    // console.log('userList 查询结果', userList)

    // 查询单条数据,返回的对象
    const user = await User.findOne({
   
    username: 'zhang' })
    console.log('user 查询结果', user)
})()

新建文件夹更新删除

// 使用 model 操作数据

const {
   
    User } = require('./model')

// 定义一个 async 的匿名函数,并执行。为了里面能用 await
!(async () => {
   
   
    // // 更新
    // const updateResult = await User.findOneAndUpdate(
    //     { username: 'zhangsan' }, // 条件
    //     { age: 30 }, // 更新的内容
    //     {
   
   
    //         new: true // 返回更新后的数据
    //     }
    // )
    // console.log('更新的返回结果', updateResult)

    // // 删除
    // const removeResult = await User.remove({ username: 'lisi' })
    // console.log('删除的返回结果', removeResult)
})()

session cookie

cookie

image.png
在koa2使用cookie

image.png
session是在服务端存储的用户信息

image.png

image.png
image.png

koa2使用session,解决跨域

  • npm i koa-generic-session --save// npm i koa2-cors --save
  • 通过ctx.session使用session
  • 在appjs写
const session = require('koa-generic-session')
const cors = require('koa2-cors')
//cors配置
app.use(cors({
   
   
    origin: 'http://localhost:8080',//前端origin
    credentials:true //允许跨域带cookie
}))
//session配置
app.keys = ['wertwe^&&*UUI123123'] // 秘钥
    // 自定配置了 cookie 和 session
app.use(session({
   
   
    // 配置 cookie
    cookie: {
   
   
        path: '/', // cookie 在根目录下有效
        httpOnly: true, // cookie 只允许服务端来操作
        maxAge: 24 * 60 * 60 * 1000 // cookie 的过期时间
    }
}))
  • 在controller层设置session ctx.session.userInfo={username}
  • 使用session的数据 const username = ctx.session.userInfo.username

    开发流程

    数据库

  • mongodb创建数据库和集合
  • 使用mongoose定义schema和model

    规范目录

    新建文件夹
    image.png
    image.png
  • 移动之后在bin-www修改app require('../src/app')

    统一返回类

    成功
    class SuccessModel{
         
         
     constructor(data){
         
         
     this.errno = 0
     if(data!=null){
         
         
     this.data=data
     }
    }
    }
    module.exports = SuccessModel
    
    失败
    class ErrorModel{
         
         
     constructor(errno=-1,message='error'){
         
         
     this.errno = errno
     this.message=message
    }
    }
    module.exports = ErrorModel
    
    如何使用
ctx.body = new SuccessModel(data)
ctx.body = new ErrorModel(10001,`注册失败 - ${
     
     ex.message}`)

登录验证中间件

image.png

router.get('/:id',loginCheck,async function (ctx,next)//loginCheck是中间件,使用前需要require。如果没登陆,不允许访问

Redis

发布订阅
subscribe zhang fang 监听多个管道
publish zhang "hello" 发送信息

相关文章
|
5月前
|
JavaScript 前端开发 安全
【逆向】Python 调用 JS 代码实战:使用 pyexecjs 与 Node.js 无缝衔接
本文介绍了如何使用 Python 的轻量级库 `pyexecjs` 调用 JavaScript 代码,并结合 Node.js 实现完整的执行流程。内容涵盖环境搭建、基本使用、常见问题解决方案及爬虫逆向分析中的实战技巧,帮助开发者在 Python 中高效处理 JS 逻辑。
|
Web App开发 JavaScript 前端开发
Node.js 是一种基于 Chrome V8 引擎的后端开发技术,以其高效、灵活著称。本文将介绍 Node.js 的基础概念
Node.js 是一种基于 Chrome V8 引擎的后端开发技术,以其高效、灵活著称。本文将介绍 Node.js 的基础概念,包括事件驱动、单线程模型和模块系统;探讨其安装配置、核心模块使用、实战应用如搭建 Web 服务器、文件操作及实时通信;分析项目结构与开发流程,讨论其优势与挑战,并通过案例展示 Node.js 在实际项目中的应用,旨在帮助开发者更好地掌握这一强大工具。
494 1
|
10月前
|
存储 JavaScript 前端开发
在NodeJS中使用npm包进行JS代码的混淆加密
总的来说,使用“javascript-obfuscator”包可以帮助我们在Node.js中轻松地混淆JavaScript代码。通过合理的配置,我们可以使混淆后的代码更难以理解,从而提高代码的保密性。
1038 9
|
11月前
|
NoSQL 关系型数据库 MongoDB
接口管理工具深度对比:Apipost与Apifox在Redis/MongoDB支持上的关键差异
近期在团队工具选型时,系统对比了Apifox和Apipost两款接口管理工具,我们的体会是:Apipost适合需要同时管理多种数据库的中大型项目,特别是涉及Redis/MongoDB等非关系型数据库的场景,Apifox仅建议在纯关系型数据库架构且预算有限的小型项目中短期使用。
389 3
|
存储 NoSQL JavaScript
Node.js导入MongoDB具体操作指南
通过本文,您已经学会了如何在Node.js中导入MongoDB并执行基本的CRUD操作。Node.js与MongoDB的结合使得构建高效、可扩展的后端服务变得更加容易。通过遵循本文的步骤,您可以快速设置并运行一个强大的数据存储和处理系统。希望这篇指南能为您的开发工作提供实用的帮助。
361 13
|
存储 NoSQL MongoDB
Redis在中国火爆,为何MongoDB更受欢迎国外?
本文介绍了Redis和MongoDB的基本概念及其在GitHub Star、DB-Engines Ranking和Google Trends中的数据对比。Redis是一个基于内存的键值对存储数据库,适合快速读写场景;MongoDB则是面向文档的数据库,支持大规模数据存储和复杂查询。全球范围内,MongoDB的搜索热度高于Redis,但在中国市场,Redis更受欢迎,因其高性能和低延迟特性满足了中国互联网公司对高并发的需求。总结部分分析了两者的特点及适用场景,并结合中美两国的行业背景解释了其受欢迎程度的不同原因。
452 1
|
存储 JavaScript NoSQL
Node.js新作《循序渐进Node.js企业级开发实践》简介
《循序渐进Node.js企业级开发实践》由清华大学出版社出版,基于Node.js 22.3.0编写,包含26个实战案例和43个上机练习,旨在帮助读者从基础到进阶全面掌握Node.js技术,适用于初学者、进阶开发者及全栈工程师。
254 9
|
JSON JavaScript 前端开发
使用JavaScript和Node.js构建简单的RESTful API
使用JavaScript和Node.js构建简单的RESTful API
|
开发框架 JavaScript 前端开发
Node.js日记:客户端和服务端介绍、Node.js介绍
Node.js日记:客户端和服务端介绍、Node.js介绍

推荐镜像

更多