nodejs实现一个用户只能点一次赞功能

2025-04-14 23

Image

nodejs实现一个用户只能点一次赞功能

在开发社交应用或内容平台时,我们常常需要实现用户对某个内容(如、图片等)只能点赞一次的功能。提供几种解决方案,并通过代码示例详细展示如何实现这一功能。

解决方案

为了确保用户只能对某个内容点赞一次,我们需要记录用户的点赞行为。通常可以通过以下方式实现:
1. 使用数据库存储用户的点赞状态。
2. 利用缓存技术(如Redis)来快速判断用户是否已点赞。
3. 结合JWT(JSON Web Token)或其他会话管理机制,确保每个用户的性。

接下来,我们将从不同的角度和思路来实现这一功能。


思路一:使用关系型数据库

我们可以使用关系型数据库(如MySQL、PostgreSQL)来存储用户的点赞记录。以下是具体实现步骤:

数据库设计

假设我们有一个 likes 表,结构如下:
- id: 自增主键
- user_id: 用户ID
- content_id: 内容ID(如ID)
- created_at: 点赞时间

实现代码

javascript
const express = require('express');
const mysql = require('mysql');
const app = express();
app.use(express.json());</p>

<p>// 创建MySQL连接池
const pool = mysql.createPool({
  host: 'localhost',
  user: 'root',
  password: 'password',
  database: 'my_database'
});</p>

<p>// 点赞接口
app.post('/like/:contentId', (req, res) => {
  const userId = req.body.userId; // 假设从前端传递用户ID
  const contentId = req.params.contentId;</p>

<p>// 查询用户是否已经点赞
  pool.query('SELECT * FROM likes WHERE user<em>id = ? AND content</em>id = ?', [userId, contentId], (err, results) => {
    if (err) {
      return res.status(500).send('Database error');
    }</p>

<pre><code>if (results.length > 0) {
  // 如果用户已点赞,则返回错误信息
  return res.status(400).send('You have already liked this content');
} else {
  // 否则插入新的点赞记录
  pool.query('INSERT INTO likes (user_id, content_id, created_at) VALUES (?, ?, NOW())', [userId, contentId], (err, result) => {
    if (err) {
      return res.status(500).send('Database error');
    }
    res.status(200).send('Like successful');
  });
}

});
});

// 启动服务器
app.listen(3000, () => {
console.log('Server is running on port 3000');
});


思路二:使用Redis缓存

如果需要更高效的性能,可以使用Redis来存储用户的点赞状态。Redis的键值对存储非常适合这种场景。

实现代码

javascript
const express = require('express');
const redis = require('redis');
const app = express();
app.use(express.json());</p>

<p>// 创建Redis客户端
const client = redis.createClient({
  host: 'localhost',
  port: 6379
});</p>

<p>client.on('error', (err) => {
  console.error('Redis error:', err);
});</p>

<p>// 点赞接口
app.post('/like/:contentId', (req, res) => {
  const userId = req.body.userId; // 假设从前端传递用户ID
  const contentId = req.params.contentId;
  const likeKey = <code>like:${userId}:${contentId};

// 检查用户是否已经点赞 client.get(likeKey, (err, reply) => { if (err) { return res.status(500).send('Redis error'); }

if (reply) {
  // 如果用户已点赞,则返回错误信息
  return res.status(400).send('You have already liked this content');
} else {
  // 否则设置点赞状态
  client.setex(likeKey, 86400, 'true', (err) => { // 设置过期时间为1天
    if (err) {
      return res.status(500).send('Redis error');
    }
    res.status(200).send('Like successful');
  });
}

});
});

// 启动服务器
app.listen(3000, () => {
console.log('Server is running on port 3000');
});


思路三:结合JWT与后端验证

如果我们的应用使用了JWT进行身份验证,可以在JWT中嵌入用户的标识,并在后端验证用户是否已点赞。

实现代码

javascript
const express = require('express');
const jwt = require('jsonwebtoken');
const mysql = require('mysql');
const app = express();
app.use(express.json());</p>

<p>// 创建MySQL连接池
const pool = mysql.createPool({
  host: 'localhost',
  user: 'root',
  password: 'password',
  database: 'my_database'
});</p>

<p>// JWT密钥
const secretKey = 'your<em>secret</em>key';</p>

<p>// 验证JWT中间件
function authenticateToken(req, res, next) {
  const authHeader = req.headers['authorization'];
  const token = authHeader && authHeader.split(' ')[1];
  if (token == null) return res.sendStatus(401);</p>

<p>jwt.verify(token, secretKey, (err, user) => {
    if (err) return res.sendStatus(403);
    req.user = user;
    next();
  });
}</p>

<p>// 点赞接口
app.post('/like/:contentId', authenticateToken, (req, res) => {
  const userId = req.user.id; // 从JWT中获取用户ID
  const contentId = req.params.contentId;</p>

<p>// 查询用户是否已经点赞
  pool.query('SELECT * FROM likes WHERE user<em>id = ? AND content</em>id = ?', [userId, contentId], (err, results) => {
    if (err) {
      return res.status(500).send('Database error');
    }</p>

<pre><code>if (results.length > 0) {
  // 如果用户已点赞,则返回错误信息
  return res.status(400).send('You have already liked this content');
} else {
  // 否则插入新的点赞记录
  pool.query('INSERT INTO likes (user_id, content_id, created_at) VALUES (?, ?, NOW())', [userId, contentId], (err, result) => {
    if (err) {
      return res.status(500).send('Database error');
    }
    res.status(200).send('Like successful');
  });
}

});
});

// 登录接口(生成JWT)
app.post('/login', (req, res) => {
const user = { id: req.body.userId }; // 假设用户登录成功后返回用户ID
const accessToken = jwt.sign(user, secretKey, { expiresIn: '1h' });
res.json({ accessToken });
});

// 启动服务器
app.listen(3000, () => {
console.log('Server is running on port 3000');
});


以上三种思路分别使用了关系型数据库、Redis缓存以及JWT结合后端验证的方式实现了用户只能点赞一次的功能。每种方法都有其适用场景:
- 关系型数据库适合数据持久化需求较高的场景。
- Redis缓存适合对性能要求较高且数据不需要长期保存的场景。
- JWT结合后端验证适合已有身份验证机制的应用。

根据实际需求选择合适的方案即可!

1. 本站所有资源来源于用户上传和网络,因此不包含技术服务请大家谅解!如有侵权请邮件联系客服!cheeksyu@vip.qq.com
2. 本站不保证所提供下载的资源的准确性、安全性和完整性,资源仅供下载学习之用!如有链接无法下载、失效或广告,请联系客服处理!
3. 您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容资源!如用于商业或者非法用途,与本站无关,一切后果请用户自负!
4. 如果您也有好的资源或教程,您可以投稿发布,成功分享后有积分奖励和额外收入!
5.严禁将资源用于任何违法犯罪行为,不得违反国家法律,否则责任自负,一切法律责任与本站无关

源码下载