node.js实战一文带你开发博客项目之koa2重构(实现session开发路由联调日志)(代码片段)

前端杂货铺 前端杂货铺     2023-03-07     465

关键词:

个人简介

👀个人主页: 前端杂货铺
🙋‍♂️学习方向: 主攻前端方向,也会涉及到服务端
📃个人状态: 在校大学生一枚,已拿多个前端 offer(秋招)
🚀未来打算: 为中国的工业软件事业效力n年
🥇推荐学习:🍍前端面试宝典 🍉Vue2 🍋Vue3 🍓Vue2&Vue3项目实战 🥝Node.js🍒Three.js
🌕个人推广:每篇文章最下方都有加入方式,旨在交流学习&资源分享,快加入进来吧

Node.js系列文章目录

内容参考链接
Node.js(一)初识 Node.js
Node.js(二)Node.js——开发博客项目之接口
Node.js(三)Node.js——一文带你开发博客项目(使用假数据处理)
Node.js(四)Node.js——开发博客项目之MySQL基础
Node.js(五)Node.js——开发博客项目之API对接MySQL
Node.js(六)Node.js——开发博客项目之登录(前置知识)
Node.js(七)Node.js——开发博客项目之登录(对接完毕)
Node.js(八)Node.js——开发开发博客项目之联调
Node.js(九)Node.js——开发博客项目之日志
Node.js(十)Node.js——开发博客项目之安全
Node.js(十 一)Node.js——开发博客项目之初识 Express
Node.js(十二)Node.js——开发博客项目之 Express 重构

文章目录


一、前言

前面我们介绍了 await / async 的基本使用,学到了 koa2 框架的安装、项目的创建,以及路由的基本使用。

接下来,我们正式使用 koa2 对我们的 myblog 博客项目进行重构!

二、实现 session

终端安装一些必要的东西(koa-generic-session、koa-redis、redis),更容易实现登录

npm i koa-generic-session koa-redis redis

修改 app.js 文件

app.js

const session = require('koa-generic-session')
const redisStore = require('koa-redis')
......
// session 配置(在routes前面)
app.keys = ['Qianduan2023']
app.use(session(
  // 配置 cookier
  cookie: 
    path: '/',
    httpOnly: true,
    maxAge: 24 * 60 * 60 * 1000
  ,
  // 配置 redis
  store: redisStore(
    all: '127.0.0.1:6379' // 本地 reids
  )
))

我们在 user.js 中创建一个 session-test 做测试

user.js

router.get('/session-test', async function(ctx, next) 
    if (ctx.session.viewCount == null) 
        ctx.session.viewCount = 0
    
    
    ctx.session.viewCount++

    ctx.body = 
        errno: 0,
        viewCount: ctx.session.viewCount
    
)


三、开发路由

1、安装 mysql 和 xss

终端键入以下代码,安装 mysql 和 xss

npm i mysql xss

2、代码迁移

修改 app.js 文件,修改本地 redis 的写法

app.js

const  REDIS_CONF  = require('./conf/db')
......
  // 配置 redis
  store: redisStore(
    // all: '127.0.0.1:6379' // 本地 reids
    all: `$REDIS_CONF.host:$REDIS_CONF.port`
  )

3、修改 controller 控制器

修改 controller 文件里的内容(主要是修改成 async/await 的形式)

./controller.blog.js

// 导入执行 sql 的相关内容
const xss = require('xss')
const  exec  = require('../db/mysql')

// 获取博客列表(通过作者和关键字)
const getList = async (author, keyword) => 
    // 1=1 是为了语法的绝对正确,注意以下 sql 拼接时的空格
    let sql = `select * from blogs where 1=1 `
    if (author) 
        sql += `and author='$author' `
    
    if (keyword) 
        sql += `and title like '%$keyword%' `
    
    // 以时间的倒序
    sql += `order by createtime desc;`

    // 返回 promise
    return await exec(sql)


// 获取博客详情(通过 id)
const getDetail = async (id) => 
    const sql = `select * from blogs where id='$id'`
    const rows = await exec(sql)
    return rows[0]


// 新建博客 newBlog 若没有,就给它一个空对象
const newBlog = async (blogData = ) => 
    // blogData 是一个博客对象,包含 title content author 属性
    const title = xss(blogData.title)
    const content = xss(blogData.content)
    const author = blogData.author
    const createTime = Date.now()

    const sql = `
                insert into blogs (title, content, createtime, author)
                values ('$title', '$content', '$createTime', '$author');
    `

    const insertData = await exec(sql)
    return 
        id: insertData.insertId
    


// 更新博客(通过 id 更新)
const updateBlog = async (id, blogData = ) => 
    // id 就是要更新博客的 id
    // blogData 是一个博客对象 包含 title content 属性
    const title = xss(blogData.title)
    const content = xss(blogData.content)

    const sql = `
        update blogs set title='$title', content='$content' where id=$id
    `

    const updateData = await exec(sql)
    // 更新的影响行数大于 0,则返回 true
    if (updateData.affectedRows > 0) 
        return true
    
    return false


// 删除博客(通过 id 删除)
const delBlog = async (id, author) => 
    const sql = `delete from blogs where id='$id' and author='$author'`
    
    const delData = await exec(sql)
    if (delData.affectedRows > 0) 
        return true
    
    return false


// 导出共享
module.exports = 
    getList,
    getDetail,
    newBlog,
    updateBlog,
    delBlog

./controller/user.js

const  exec, escape  = require('../db/mysql')
const  genPassword  = require('../utils/cryp')
// 登录(通过用户名和密码)
const login = async (username, password) => 
    username = escape(username)
    
    // 生成加密密码
    password = genPassword(password)
    password = escape(password)

    const sql = `
        select username, realname from users where username=$username and password=$password
    `

    const rows = await exec(sql)
    return rows[0]
    


// 导出共享
module.exports = 
    login

4、开发路由

开发 ./routes 文件里的路由,直接拷贝 blog-express 文件里的内容,使用 koa2 规定的格式即可

./routes/blog.js

const router = require('koa-router')()
// 导入博客和用户控制器相关内容
const 
    getList,
    getDetail,
    newBlog,
    updateBlog,
    delBlog
 = require('../controller/blog')
// 导入成功和失败的模型
const 
    SuccessModel,
    ErrorModel
 = require('../model/resModel')

const loginCheck = require('../middleware/loginCheck')
// 前缀
router.prefix('/api/blog')

router.get('/list', async function (ctx, next) 
    // 博客的作者,req.query 用在 GET 请求中
    let author = ctx.query.author || ''
    // 博客的关键字
    const keyword = ctx.query.keyword || ''

    if (ctx.query.isadmin) 
        // 管理员界面
        if (ctx.session.username == null) 
            // 未登录
            ctx.body = new ErrorModel('未登录')
            return
        
        // 强制查询自己的博客
        author = ctx.session.username
    

    // 查询的结果
    const listData = await getList(author, keyword)
    ctx.body = new SuccessModel(listData)
)

router.get('/detail', async function (ctx, next) 
    const data = await getDetail(ctx.query.id)
    ctx.body = new SuccessModel(data)
)

router.post('/new', loginCheck, async function (ctx, next) 
    const body = ctx.request.body
    body.author = ctx.session.username
    const data = await newBlog(body)
    ctx.body = new SuccessModel(data)
)

router.post('/update', loginCheck, async function (ctx, next) 
    const val = await updateBlog(ctx.query.id, ctx.body)
    if (val) 
        ctx.body = new SuccessModel()
     else 
        ctx.body = new ErrorModel('更新博客失败')
    
)

router.post('/del', loginCheck, async function (ctx, next) 
    const author = ctx.session.username
    const val = await delBlog(ctx.query.id, author)
    if (val) 
        ctx.body = new SuccessModel()
     else 
        ctx.body = new ErrorModel('删除博客失败')
    
)

module.exports = router

./routes/user.js

const router = require('koa-router')()
const  login  = require('../controller/user')
const  SuccessModel, ErrorModel  = require('../model/resModel')

// 前缀
router.prefix('/api/user')

// 路由的中间件必须是个 async 函数
router.post('/login', async function (ctx, next) 
    // 通过 request.body 获取
    const  username, password  = ctx.request.body
    const data = await login(username, password)
    
    if (data.username) 
        // 设置 session
        ctx.session.username = data.username
        ctx.session.realname = data.realname

        ctx.body = new SuccessModel()
        return
    
        ctx.body = new ErrorModel('登录失败')
)

module.exports = router

四、联调

启动 redis,开启 nginx
后端:npm run dev
前端:http-server -p 8001


五、日志

终端键入安装 koa-morgan

npm i koa-morgan

修改 app.js 文件

app.js

const path = require('path')
const fs = require('fs')
const morgan = require('koa-morgan')
......
// 日志记录
const ENV = process.env.NODE_ENV
if (ENV !== 'production') 
  // 开发环境 / 测试环境
  app.use(morgan('dev'))
 else 
  // 线上环境使用 combined(写入文件)
  const logFileName = path.join(__dirname, 'logs', 'access.log')
  const writeStream = fs.createWriteStream(logFileName, 
    flags: 'a'
  )
  app.use(morgan('combined', 
    stream: writeStream
  ));

同样的,修改 package.json 文件

package.json

"prd": "cross-env NODE_ENV=production nodemon ./bin/www"

npm run prd,运行文件,之后打开几个页面,查看 access.log 文件的内容


六、写在最后

至此,我们明白了 如何使用 Koa2 框架对我们的 myblog 项目进行进一步的重构(实现session、开发路由、联调、日志), 本系列文章暂告一段落!

如果你需要该项目的 源码,请通过本篇文章最下面的方式 加入 进来~~



node.js实战一文带你开发博客项目之安全(sql注入xss攻击md5加密算法)(代码片段)

...4d;前端面试宝典🍉Vue2🍋Vue3🍓Vue2&Vue3项目实战🥝Node.js🍒Three.js🌕个人推广:每篇文章最下方都有加入方式,旨在交流学习&资源分享,快加入进来吧Node.js系列文章目录内容参考链接Node.j... 查看详情

node.js实战一文带你开发博客项目之安全(sql注入xss攻击md5加密算法)(代码片段)

...4d;前端面试宝典🍉Vue2🍋Vue3🍓Vue2&Vue3项目实战🥝Node.js🍒Three.js🌕个人推广:每篇文章最下方都有加入方式,旨在交流学习&资源分享,快加入进来吧Node.js系列文章目录内容参考链接Node.j... 查看详情

node.js实战一文带你开发博客项目之安全(sql注入xss攻击md5加密算法)(代码片段)

...4d;前端面试宝典🍉Vue2🍋Vue3🍓Vue2&Vue3项目实战🥝Node.js🍒Three.js🌕个人推广:每篇文章最下方都有加入方式,旨在交流学习&资源分享,快加入进来吧Node.js系列文章目录内容参考链接Node.j... 查看详情

node.js实战一文带你开发博客项目之安全(sql注入xss攻击md5加密算法)(代码片段)

...4d;前端面试宝典🍉Vue2🍋Vue3🍓Vue2&Vue3项目实战🥝Node.js🍒Three.js🌕个人推广:每篇文章最下方都有加入方式,旨在交流学习&资源分享,快加入进来吧Node.js系列文章目录内容参考链接Node.j... 查看详情

node.js实战一文带你开发博客项目之安全(sql注入xss攻击md5加密算法)(代码片段)

...4d;前端面试宝典🍉Vue2🍋Vue3🍓Vue2&Vue3项目实战🥝Node.js🍒Three.js🌕个人推广:每篇文章最下方都有加入方式,旨在交流学习&资源分享,快加入进来吧Node.js系列文章目录内容参考链接Node.j... 查看详情

node.js实战一文带你开发博客项目(api对接mysql)(代码片段)

...4d;前端面试宝典🍉Vue2🍋Vue3🍓Vue2&Vue3项目实战🥝Node.js🌕个人推广:每篇文章最下方都有加入方式,旨在交流学习&资源分享,快加入进来吧Node.js系列文章目录内容参考链接Node.js(一ÿ... 查看详情

node.js实战一文带你开发博客项目之联调(导入htmlnginx反向代理cors解决跨域与前端联调)(代码片段)

...4d;前端面试宝典🍉Vue2🍋Vue3🍓Vue2&Vue3项目实战🥝Node.js🍒Three.js🌕个人推广:每篇文章最下方都有加入方式,旨在交流学习&资源分享,快加入进来吧Node.js系列文章目录内容参考链接Node.j... 查看详情

node.js实战一文带你开发博客项目(mysql基础)(代码片段)

...4d;前端面试宝典🍉Vue2🍋Vue3🍓Vue2&Vue3项目实战🥝Node.js🌕个人推广:每篇文章最下方都有加入方式,旨在交流学习&资源分享,快加入进来吧Node.js系列文章目录内容参考链接Node.js(一ÿ... 查看详情

node.js实战一文带你开发博客项目之联调(导入htmlnginx反向代理cors解决跨域与前端联调)(代码片段)

个人简介👀个人主页:前端杂货铺🙋‍♂️学习方向:主攻前端方向,也会涉及到服务端📃个人状态:在校大学生一枚,已拿多个前端offer(秋招)🚀未来打算:为中国的工业软件... 查看详情

node.js实战一文带你开发博客项目(使用假数据处理)(代码片段)

...4d;前端面试宝典🍉Vue2🍋Vue3🍓Vue2&Vue3项目实战🥝Node.js🌕个人推广:每篇文章最下方都有加入方式,旨在交流学习&资源分享,快加入进来吧Node.js系列文章目录内容参考链接Node.js(一ÿ... 查看详情

ikcamp|基于koa2搭建node.js实战(含视频)?记录日志

沪江CCtalk视频地址:https://www.cctalk.com/v/15114923883523log日志中间件最困难的事情就是认识自己。在一个真实的项目中,开发只是整个投入的一小部分,版本迭代和后期维护占了极其重要的部分。项目上线运转起来之后,我们如何知... 查看详情

熬夜之作:一文带你了解cat分布式监控(代码片段)

Cat是什么?CAT(CentralApplicationTracking)是基于Java开发的实时应用监控平台,包括实时应用监控,业务监控。CAT作为服务端项目基础组件,提供了Java,C/C++,Node.js,Python,Go等多语言客户端,已经在美团点评的基础架构中间件框架(MVC... 查看详情

开始连载啦~每周2更共11堂ikcamp课|基于koa2搭建node.js实战项目教学(含视频)|课程大纲介绍

...案讲解+视频演示,文字可激发深层的思考、视频可还原实战操作过程。云集一线大厂有真正实力的程序员iKcamp团队云集一线大厂经验丰厚的码农,开源奉献各教程。改版自真实的线上项目教程项目并非网上随意Demo,而是来源于... 查看详情

『python开发实战菜鸟教程』实战篇:一文带你了解人脸识别应用原理及手把手教学实现自己的人脸识别项目(代码片段)

文章目录0x01:引子0x02:环境搭建0x03:开发实战 1.实现人脸检测标记2.人脸特征点提取3.人脸识别验证0x04:后记开源GitHub地址--> https://github.com/xiaosongshine/dlib_face_recognition推荐补充阅读:『Python开发实战菜鸟... 查看详情

ikcamp|基于koa2搭建node.js实战(含视频)?代码分层

视频地址:https://www.cctalk.com/v/15114923889408文章在前面几节中,我们已经实现了项目中的几个常见操作:启动服务器、路由中间件、Get和Post形式的请求处理等。现在你已经迈出了走向成功的第一步。目前,整个示例中所有的代码... 查看详情

node.js+vue+mysql项目实战入门之环境搭建,项目创建-附github地址(代码片段)

Node进行后端开发,Vue进行前端页面的开发,实现了前后端的分离。在开发中使用Express框架可以快速地开发web应用程序。1.安装node.js下载对应版本的,网址:Download|Node.js;进行傻瓜式安装:最后点击install... 查看详情

node.js+vue+mysql项目实战入门之环境搭建,项目创建-附github地址(代码片段)

Node进行后端开发,Vue进行前端页面的开发,实现了前后端的分离。在开发中使用Express框架可以快速地开发web应用程序。 1.安装node.js下载对应版本的,网址:https://nodejs.org/en/download/;进行傻瓜式安装:最... 查看详情

一文带你认识nodejs

​node.js初探Node.js是一个JS的服务端运行环境,简单的来说,它是在JS语言规范的基础上,封装了一些服务端的运行时对象,让我们能够简单实现非常多的业务功能。如果我们只使用JS的话,实际上只是能进行一些简单的逻辑运算... 查看详情