新手求教:如何用Node.js+MySQL实现动态关注/取消关注按钮?
嘿,我来帮你搞定这个动态关注按钮的问题,顺便给你推荐些实用的学习资源!
一、实现动态关注/取消关注按钮(无刷新)
这个需求核心是前端用异步请求发指令+后端处理双向状态+页面实时更新,分步骤拆解:
1. 前端Profile.ejs的调整
首先要解决两个问题:传递目标用户ID,以及初始状态的正确渲染。
第一步:渲染初始按钮状态
后端渲染Profile页面时,要先查询当前用户是否已经关注了目标用户,把状态传给EJS模板。然后把原来的表单改成带状态标识的按钮:
<!-- 假设从后端拿到了目标用户ID(targetUserId)和是否已关注(isFollowing) --> <button class="follow-btn btn btn-primary a-btn-slide-text" data-user-id="<%= targetUserId %>" data-is-following="<%= isFollowing %>"> <%= isFollowing ? 'Unfollow' : 'Follow' %> </button>
第二步:添加异步交互逻辑
在EJS页面底部(或单独的JS文件)加一段JavaScript,监听按钮点击,用Fetch API发送无刷新请求:
document.querySelectorAll('.follow-btn').forEach(btn => { btn.addEventListener('click', async function(e) { e.preventDefault(); const targetUserId = this.dataset.userId; const isFollowing = this.dataset.isFollowing === 'true'; try { const response = await fetch('/follow', { method: 'POST', headers: { 'Content-Type': 'application/json', // 若用了session/passport,记得加CSRF token,比如从meta标签获取后加到headers里 }, body: JSON.stringify({ followee_id: targetUserId, action: isFollowing ? 'unfollow' : 'follow' }) }); const result = await response.json(); if (result.success) { // 更新按钮状态 this.dataset.isFollowing = result.isFollowing.toString(); this.textContent = result.isFollowing ? 'Unfollow' : 'Follow'; // 可选:同步更新页面上的关注数、粉丝数等数据 } } catch (err) { console.error('操作失败:', err); alert('关注/取消关注失败,请重试'); } }); });
2. 后端路由的改造
原来的路由只处理了关注,现在要同时支持取消关注,并且返回JSON而非重定向:
app.post("/follow", async function(req, res) { const { followee_id, action } = req.body; const follower_id = req.user.id; // 替换成你获取当前用户ID的方式(比如session) try { if (action === 'follow') { // 新增关注关系,建议给follows表加(follower_id, followee_id)的唯一约束,避免重复关注 await connection.query('INSERT INTO follows (follower_id, followee_id) VALUES (?, ?)', [follower_id, followee_id]); res.json({ success: true, isFollowing: true }); } else if (action === 'unfollow') { // 删除关注关系 await connection.query('DELETE FROM follows WHERE follower_id = ? AND followee_id = ?', [follower_id, followee_id]); res.json({ success: true, isFollowing: false }); } else { res.status(400).json({ success: false, message: '无效操作' }); } } catch (err) { console.error('数据库操作失败:', err); res.status(500).json({ success: false, message: '服务器错误' }); } });
补充:渲染Profile页面时的状态查询
在渲染Profile的路由里,要先判断当前用户与目标用户的关注关系:
app.get("/profile/:userId", async function(req, res) { const targetUserId = req.params.userId; const currentUserId = req.user.id; // 你的当前用户ID获取方式 // 查询目标用户信息(省略) // 查询是否已关注 const [followResult] = await connection.query('SELECT * FROM follows WHERE follower_id = ? AND followee_id = ?', [currentUserId, targetUserId]); const isFollowing = followResult.length > 0; res.render('Profile', { targetUserId, isFollowing, // 其他需要传递的用户信息 }); });
3. 关键注意事项
- CSRF防护:如果用Express,建议用
csurf中间件,前端要在请求里带上CSRF token,避免跨站请求伪造。 - 数据库约束:给follows表添加
UNIQUE(follower_id, followee_id)约束,防止重复插入关注关系。 - 错误处理:前端要处理网络错误、服务器错误等情况,给用户友好提示。
二、Node.js结合动态JavaScript交互的学习资源推荐
- 官方基础文档
- Express官方指南:吃透路由、中间件、请求响应逻辑,这是后端交互的核心基础。
- MDN Fetch API文档:深入掌握前端异步请求的实现,是动态交互的关键。
- 实战类资源
- 《Node.js实战》书籍:里面有大量全栈项目案例,覆盖前后端交互的完整流程,适合进阶。
- 「Node.js + Express 社交平台」类实战教程:跟着从零搭建类似Twitter的小应用,能直观理解动态交互的实现逻辑。
- 社区与进阶
- 常逛Stack Overflow的Node.js/Express标签:看他人的实战问题和解决方案,积累踩坑经验。
- 全栈开发视频系列:比如从0到1实现带动态交互的博客/社交应用,可视化学习前后端配合的细节。
内容的提问来源于stack exchange,提问作者MG91
相关产品推荐
相关产品推荐

