如何在Flask中实现无页面刷新提交表单完成记录点赞功能?
无刷新点赞功能实现方案
要实现无刷新点赞,核心是用AJAX异步提交点赞请求,替换原有表单同步提交逻辑,具体修改如下:
1. 后端Flask代码修改
原有路由是同步表单提交,会返回完整页面导致刷新,我们需要新增一个独立的点赞接口,返回JSON数据:
# 新增点赞接口 @app.route('/upvote', methods=['POST']) def upvote(): # 校验CSRF,和原有表单逻辑一致 if not request.is_json: return {"code": 400, "msg": "请求格式错误"}, 400 record_id = request.json.get('record_id') item = Row.query.filter_by(id=record_id).first() if not item: return {"code": 404, "msg": "记录不存在"}, 404 # 更新点赞数 item.rating += 1 db.session.commit() # 返回新的点赞数 return {"code": 200, "new_rating": item.rating} # 原有form路由可以保留,只要不处理点赞的提交逻辑即可,不需要额外修改
2. 前端HTML模板修改
首先修改DOM结构,移除不必要的隐藏输入框,给按钮添加自定义属性存记录ID,再添加异步请求逻辑:
{{form.csrf_token }} <div class="record-list"> {% for item in records %} <div class="record-item"> <span class="rating-num">{{ item.rating }}</span> <!-- 直接把记录ID存在按钮的data属性里,不需要隐藏input --> <button class="upvote-btn" data-id="{{ item.id }}">Upvote +1</button> </div> {% endfor %} </div> <script> // 拿CSRF令牌,Flask-WTF生成的隐藏域name是csrf_token const csrfToken = document.querySelector('input[name="csrf_token"]').value; // 给所有点赞按钮绑定点击事件 document.querySelectorAll('.upvote-btn').forEach(btn => { btn.addEventListener('click', async function(e) { // 阻止默认的表单提交行为 e.preventDefault(); const recordId = this.dataset.id; const ratingEl = this.previousElementSibling; try { const res = await fetch('/upvote', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRFToken': csrfToken }, body: JSON.stringify({record_id: recordId}) }); const data = await res.json(); if (data.code === 200) { // 直接更新页面上的点赞数,不需要刷新 ratingEl.textContent = data.new_rating; // 可选:点赞后禁用按钮防止重复提交 this.disabled = true; this.textContent = "已点赞"; } else { alert(data.msg || '点赞失败'); } } catch (err) { alert('网络错误,点赞失败'); } }); }); </script>
注意事项
- 上述代码用原生JavaScript实现,不需要引入jQuery等额外库
- 若你需要支持用户重复点赞/取消点赞,可扩展后端接口逻辑,存储用户点赞状态,前端对应调整交互即可
- 原有表单的提交逻辑如果没有其他用途,可以直接移除,避免冲突
内容的提问来源于stack exchange,提问作者Max Reva
相关产品推荐
相关产品推荐

