Node.js实战一文带你开发博客项目之Koa2重构(实现session开发路由联调日志)
Posted 前端杂货铺
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Node.js实战一文带你开发博客项目之Koa2重构(实现session开发路由联调日志)相关的知识,希望对你有一定的参考价值。
个人简介
👀个人主页: 前端杂货铺
🙋♂️学习方向: 主攻前端方向,也会涉及到服务端
📃个人状态: 在校大学生一枚,已拿多个前端 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实战一文带你开发博客项目之Koa2重构(实现session开发路由联调日志)的主要内容,如果未能解决你的问题,请参考以下文章
Node.js实战一文带你开发博客项目之安全(sql注入xss攻击md5加密算法)
Node.js实战一文带你开发博客项目之安全(sql注入xss攻击md5加密算法)
Node.js实战一文带你开发博客项目之安全(sql注入xss攻击md5加密算法)
Node.js实战一文带你开发博客项目之安全(sql注入xss攻击md5加密算法)