likes
comments
collection
share

富文本编辑功能实现后端部分(附源码)

作者站长头像
站长
· 阅读数 74

富文本编辑功能实现后端部分(附源码)

上一篇文章分享了富文本编辑功能实现的前端部分,所以此篇文章紧接上篇文章来说一下后端需要如何实现的(后端技术栈为koa2)🌮

上篇文章(前端项目中如何实现富文本编辑功能(含源码))链接

源码地址

一、安装配置 koa-static

koa2项目如果需要接受文件及图片等的数据,则需要安装第三方插件,因为koa2官方只提供了最基本的操作,其他的功能几乎都需要安装插件,不过好在koa2的生态还是不错的,这里我个人使用的是koa-static来处理图片的问题;

koa-static

安装

npm i koa-static
npm i @types/koa-static --save-dev

// yarn add koa-static
// yarn add @types/koa-static --save-dev

配置

// 在src/app/index.ts 文件中初始化图片上传的配置
app.use(
  KoaBody({
    multipart: true, // 开启文件上传
    formidable: {
      // 文件上传的详细配置
      // 在配制选项option里, 不推荐使用相对路径
      // 在option里的相对路径, 不是相对的当前文件. 相对process.cwd()
      uploadDir: path.join(__dirname, '../upload'), // 上传的文件放置到哪个路径下
      maxFileSize: 1000 * 1024 * 1024, // 设置上传文件大小最大限制
      keepExtensions: true // 是否保留文件的扩展名
    },
    parsedMethods: ['POST', 'PUT', 'PATCH', 'DELETE']
  })
)

// 配置静态资源网址访问
app.use(koaStatic(path.join(__dirname, '../upload')))

二、接收上传图片

配置router上传图片接口

const router = new Router({ prefix: '/common' })

// 公用上传图片接口
router.post(
  '/image',
  contrastFileSizeSchema(),  // 判断上传图片大小
  judImgFormatSchema(), // 判断上传图片的格式
  commondUploadImgMid, // 保存图片返回路径
  IndexCon('图片上传成功!') // 公用封装的返回函数
)

判断上传图片的大小

export const contrastFileSizeSchema = (limitSize = 1024 * 1024) => {
  return async (ctx: Context, next: () => Promise<void>) => {
    const { avatar } = (ctx.request as any).files
    const { size } = avatar as imgType

    if (size > limitSize) {
      console.error('图片超过大小限制')
      return ctx.app.emit('error', unAvatarSizeErr, ctx)
    }
    await next()
  }
}

判断上传图片的格式

export const judImgFormatSchema = (imgFormat = ['image/jpeg', 'image/png']) => {
  return async (ctx: Context, next: () => Promise<void>) => {
    const { avatar } = (ctx.request as any).files
    const { mimetype, filepath } = avatar as imgType
    const basePath = path.basename(filepath) as string

    if (!imgFormat.includes(mimetype)) {
      removeSpecifyFile(basePath)
      console.error('图片上传格式错误,请上传jpeg/png格式')
      return ctx.app.emit('error', unSupportedFileErr, ctx)
    }
    await next()
  }
}

公用图片上传

export const commondUploadImgMid = async (ctx: Context, next: () => Promise<void>) => {
  try {
    const { avatar } = (ctx.request as any).files
    const { filepath } = avatar as imgType
    const basePath = path.basename(filepath) as string
    const { APP_PORT } = process.env
    // os 为nodejs默认自带的查询本机服务器的默认参数
    const ip = os.networkInterfaces()['WLAN'][1].address

    ctx.state.formatData = {
      imgUrl: `http://${ip}:${APP_PORT}/${basePath}`
    }
    await next()
  } catch (error) {
    console.error('公用图片上传失败')
    return ctx.app.emit('error', uploadImageErr, ctx)
  }
}

完成上述流程后,会将图片访问地址src返回给前端,前端拿着地址即可访问图片;

三、删除上传图片

因为富文本编辑器,用户上传图片和最终保存图片可能不一致,上传图片是在用户编辑的时候上传的,最终保存的图片可能和上传的不一致,需要将多余的图片删除;

删除图片路由

// 路由body接受图片hash标识组成的数组
router.post('/delImage', commondDelImgMid, IndexCon())

删除图片中间件

// 公用删除图片
export const commondDelImgMid = async (ctx: Context, next: () => Promise<void>) => {
  try {
    const data = (ctx.request as any).body
    data.forEach((item: string) => {
       // 封装的删除文件方法
      removeSpecifyFile(item)
    })
    await next()
  } catch (error) {
    console.error('公用删除图片失败')
    return ctx.app.emit('error', delErr, ctx)
  }
}

删除文件公用函数

/** 删除文件
 * @param {string} filename
 * @return {boolean}
 */
export const removeSpecifyFile = (filename: string): boolean => {
  // filePath 为 图片存放的文件路径
  const filePath = path.join(__dirname, '../../upload')
  if (fs.existsSync(filePath)) {
    fs.unlinkSync(filePath + '/' + filename)
  } else {
    return false
  }
  return true
}

四、结语

以上便完成了富文本编辑功能的后端部分,主要难题便是图片的保存与过滤删除,其他的比如内容的存储就是和普通的存储数据一样,并没有什么难度,故而本文直接省略;如果觉得文章不错的话,欢迎点赞、收藏一键两连哦~😘

转载自:https://juejin.cn/post/7241951082792796217
评论
请登录