富文本编辑功能实现后端部分(附源码)
富文本编辑功能实现后端部分(附源码)
上一篇文章分享了富文本编辑功能实现的前端部分,所以此篇文章紧接上篇文章来说一下后端需要如何实现的(后端技术栈为koa2)🌮
一、安装配置 koa-static
koa2项目如果需要接受文件及图片等的数据,则需要安装第三方插件,因为koa2官方只提供了最基本的操作,其他的功能几乎都需要安装插件,不过好在koa2的生态还是不错的,这里我个人使用的是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