本文目录:
- 1.@符号的使用
- 2.调试Node项目的方法
- 3.mongoosejs操作
- 4.存储验证码
- 5.定义存储用户信息接口
- 6.注册接口
- 7.上传图片接口
- 8.项目运行异常问题处理
- 9.尚未解决BUG
1.@符号的使用
项目里的@符号是webpack里配置了alias才能去支持,但是也可以通过配置vscode来实现,需要借助vscode插件, Node modules resolve,安装后在项目根目录下文件 jsconfig.json中进行配置后生效。
但是暂时运行dev指令并没有使用webpack进行打包操作,所以在webpack配置文件中配置的@是不起效的,需要在package.json中配置dev指令,运行起来watch和debug指令
需要配置一个npm指令,同时运行多个npm脚本,借助插件 npm-run-all,串行的方式执行命令
"dev": "npm-run-all -p watch debug"
2.调试Node项目的方法
点击VScode左边活动栏的小齿轮,可以新添加一个配置“nodemon”,打开lauch.json文件,配置好相关代码代码后把项目本身运行的终端关闭掉
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "nodemon",
"runtimeExecutable": "${workspaceFolder}/node_modules/.bin/nodemon",
"program": "${workspaceFolder}/src/index.js",
"restart": true,
"console": "integratedTerminal",
"internalConsoleOptions": "neverOpen",
"runtimeArgs": ["--exec", "babel-node"],
}
]
}
然后选择“launch via NPM”运行项目,这时候打得断点就可以正常触发了。
如果上面这个方法一直没法触发断点,还可以选择使用chrome调试nodejs应用
先在终端npm run dev运行起来项目,
根据项目的dev脚本,控制台会打印下面这样的话
Debugger listening on ws://127.0.0.1:9229/5e9e25f0-fd40-413a-b3b2-6064f37ac353
这代表项目可以允许进行debugger
这时候在chrome中打开开发者工具中的nodejs图标,点击进入
这时候项目终端会打印debugger attached
,这代表node项目也监听到了chrome,
这时候可以在项目中相应的地方写入debugger,这时候在chrome的Node控制台就可以进行断点调试了,如本项目中的webpackConfig
同时在package.json文件中配置了可以调试webpack配置的指令npm run webpack:debug
"webpack:debug": "node --inspect-brk ./node_modules/.bin/webpack --inline --progress",
运行后在chrome打开chrome://inspect/#devices
可以调试webpack的配置。
3.mongoosejs操作
Mongoose 的一切始于 Schema。每个 schema 都会映射到一个 MongoDB collection ,并定义这个collection里的文档的构成。
本项目引用mongoose首先在config文件夹的DBHelpler.js文件中添加了连接事件的监听统一处理回调事件。
mongoosejs的增删查改:
新增一个数据,先定义好要存储的对象
const user = {
name: 'zhangsan',
age: 30,
email: 'zhangsan.com'
}
实例化Schema,然后调用save方法:
const data = new User(user)
const result = await data.save()
console.log(result)
删除指定数据:
const result = await User.deleteOne({ name: 'zhangsan' })
console.log(result)
查询数据:
const result = await User.findOne()
console.log(result)
修改数据:
const result = await User.updateOne({ name: 'zhangsan' }, {
email: 'zhangsan222.com'
})
console.log(result)
4.存储验证码
本项目将验证码存储在了Redis中,首先需要在config文件夹中新建一个RedisConfig.js文件用来定义Redis的公共操作方法,在api文件夹下的PublicController.js文件中引用RedisConfig.js定义好的setValue方法,因为是get请求,前端传递过来的参数直接就可以通过ctx.request.query获得,然后将验证码存储到Redis中,并返回状态和数据给前端
setValue(body.sid, newCaptca.text, 10 * 60)
ctx.body = {
code: 200,
data: newCaptca.data,
}
5.定义存储用户信息接口
首先在api文件夹下的LoginController.js定义login方法,因为是post方法,所以使用解构存储下来前端传递过来的body数据
const {
body
} = ctx.request
先取到sid和code去验证验证玛的正确性和时效性
因为项目中需要在多出验证验证码,所以将这个方法抽离出来,单独放在common文件夹下的utils.js中
const checkCode = async (key, value) => {
const redisData = await getValue(key)
if (redisData != null) {
if (redisData.toLowerCase() === value.toLowerCase()) {
return true
} else {
return false
}
} else {
return false
}
}
当返回值是true时代表验证码没问题,接下来验证账号和密码
let checkUserPasswd = false
let user = await User.findOne({
username: body.username
})
if (await bcrypt.compare(body.password, user.password)) {
checkUserPasswd = true
}
当checkUserPasswd为true时代表帐号密码验证没问题,接下来先将刚才从mongoDB查询到的用户信息转换为JSON对象
const userObj = user.toJSON()
并把userObj中不想返给前端的敏感数据清理掉
const arr = ['password', 'username', 'mobile']
arr.map((item) => {
delete userObj[item]
})
koa-jwt只是让koa框架拥有了jwt鉴权方式的功能,但是jwt的产生和校验还是需要借助jsonwebtoken库,利用jsonwebtoken生成token
const token = jsonwebtoken.sign({
_id: userObj._id
}, config.JWT_SECRET, {
expiresIn: '1d'
})
新增接口套路:
model文件夹中定义model,然后在api文件中定义接口处理方法,routes文件中定义接口路径,挂载api中定义的方法,并在router文件夹的routes.js中整合路由
6.注册接口
注册接口的逻辑是先查询数据库验证name和username是否有重复的,如果没有重复的,则通过new User 来生成Schema实例,然后将实例信息保存到数据库中,需要注意的一点是,密码因为是敏感数据,所以在存库前需要利用加密插件bcrypt进行处理,存储完数据后返回相应状态和数据给前端
body.password = await bcrypt.hash(body.password, 5)
let user = new User({
username: body.username,
name: body.name,
password: body.password,
created: moment().format('YYYY-MM-DD HH:mm:ss')
})
let result = await user.save()
ctx.body = {
code: 200,
data: result,
msg: '注册成功'
}
7.上传图片接口
koa在接口要成功接收到 ctx.request.files里的formdata上传的数据,需要在koa-body进行相关的配置才可以
koaBody({
multipart: true,
formidable: {
// 保留文件的后缀
keepExtensions: true,
// 允许最大体积为5M
maxFieldsSize: 5 * 1024 * 1024
},
// 监听文件上传错误
onError: err => {
console.log('文件上传出错', err)
}
}),
项目中自己定义了一个公共的递归查询并创建文件夹的方法dirExists,
其实递归创建文件夹的功能可以通过make-dir 这个库来进行快捷的实现(相当于我们自己封装的dirExists方法),但是在本项目中原生实现了
项目中安装:npm install make-dir -S
引用:import mkdir from 'make-dir'
使用:await mkdir(dir)
进行完上面的操作后,接下来获取到图片的完整名称ext,定义好图片的储存路径dir,利用uuid生成一个不重复的数字,然后将ext和dir组合成文件的唯一的完整路径+名称
const ext = file.name.split(',').pop()
const dir = `${config.uploadPath}/avatar/${mement().format('YYYYMMDD')}`
const picname = uuid()
const destPath = `${dir}/${picname}.${ext}`
读取文件流
const reader = fs.createReadStream(file.path, {
highWaterMark: 1 * 1024
})
导入文件流
const upStream = fs.createWriteStream(destPath)
利用const stat = fs.statSync(file.path)
读取到文件的总长度,然后监听文件的读取进度
let totalLength = 0
const stat = fs.statSync(file.path)
console.log('文件总长度', stat.size)
reader.on('data', (chunk) => {
totalLength += chunk.length
console.log('读取的长度', totalLength)
if (upStream.write(chunk) === false) {
reader.pause()
}
})
8.项目运行异常问题处理
1.运行项目,控制台出现报错
Package subpath './dist/v4' is not defined by "exports" in D:\000_myFile\four-leaf-boat-api\node_modules\uuid\package.json
原因:node版本切换到12.14.0,使用nvm将其切换到11.14.0就可以正常运行起来了。
9.尚未解决BUG
1.为什么上传的图片大一点就不行了?目前10kb以内可以,大于10kb不可以,无法触发接口
2.上传图片之后拿到的图片无法正常显示,访问返回401
3.踩坑:安装以来的时候bcrypt插件因为需要以来python,所以需要先手动安装python,然后手动npm install bcrypt 单独安装这个插件才行。