如何用Axios限制PATCH请求实现Nuxt+Strapi用户仅可单次评论点赞
实现方案
一、前端请求限制(防重复点击)
你当前代码没有做点击防抖和状态锁定,用户短时间多次点击会触发重复请求,可按如下逻辑改造:
- 新增
processingCommentIds数组存储正在处理点赞请求的评论ID,避免重复提交 - 新增
likedCommentIds数组存储当前用户已经点赞过的评论ID,请求成功后直接标记,无需刷新页面就能拦截重复点赞
改造后的代码如下:
data() { return { // 其他原有数据 processingCommentIds: [], likedCommentIds: [] // 页面初始化时可以从接口拉取当前用户已经点赞过的所有评论ID预存 } }, methods: { async likeComment(commentId) { // 拦截正在处理的请求 if (this.processingCommentIds.includes(commentId)) return // 拦截已经点赞过的请求 if (this.likedCommentIds.includes(commentId)) { this.$toast.error('你已经对这条评论点过赞了').goAway(5000) return } try { // 标记为处理中 this.processingCommentIds.push(commentId) await this.$axios.$patch( `${this.$config.baseURL}/comments/post:${this.contentId}/comment/${commentId}/like`, { headers: { Authorization: `Bearer ${this.$auth.$storage.getUniversal('jwt')}`, }, } ) // 标记为已点赞 this.likedCommentIds.push(commentId) this.$toast.success('Thank you for your input!').goAway(5000) // 建议直接更新本地评论列表的点赞数,不要刷新页面 // const targetComment = this.commentList.find(item => item.id === commentId) // if (targetComment) targetComment.likes += 1 } catch (e) { this.$toast.error(e).goAway(5000) } finally { // 移除处理中标记 this.processingCommentIds = this.processingCommentIds.filter(id => id !== commentId) } }, }
二、后端核心校验(唯一限制逻辑)
前端限制可以被绕过,必须在后端做校验才能真正实现单用户单评论只能点赞一次的要求,基于Strapi的实现方案如下:
- 不建议直接修改
strapi-plugin-comments的源码,你可以新增一个自定义全局中间件,拦截所有点赞/点踩请求 - 中间件逻辑:
- 从请求头的JWT解析出当前登录用户的ID
- 你可以自己新建一个
comment-reactions表,存储用户ID、评论ID、反应类型(点赞/点踩)三个核心字段 - 判断是否存在当前用户ID+当前评论ID+对应反应类型的记录:
- 存在直接返回400错误,提示重复操作
- 不存在则放行请求到插件原有接口,同时写入新的反应记录到你新建的表里
- 如果需要支持切换点赞/点踩,判断到用户已有相反类型的反应记录时,先删除旧记录再放行新请求即可。
内容的提问来源于stack exchange,提问作者Heimwerker
相关产品推荐
相关产品推荐

