让前端飞前端启示录零基础转行前端

Koa门户项目02 | 业务开发记录

2021-01-29  本文已影响0人  前端辉羽

本文目录:

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 单独安装这个插件才行。

上一篇下一篇

猜你喜欢

热点阅读