You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js无用户注册系统如何获取用户IP实现文章浏览量去重统计

基于IP去重的文章浏览量统计实现方案

第一步:正确获取用户真实IP地址

IP获取逻辑要匹配你的应用部署场景,避免拿到代理服务器的IP导致统计失效:

  • 无反向代理的本地/直连部署场景
    Express框架直接取req.ip,Koa框架取ctx.ip,Node.js原生HTTP服务可以用req.socket.remoteAddress获取IP
  • 有Nginx/CDN等反向代理的场景
    首先需要在反向代理层配置透传真实IP,以Nginx为例,在对应的站点配置块中添加以下参数:
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    
    然后在应用框架开启代理信任:Express添加配置app.set('trust proxy', 1),Koa添加配置app.proxy = true,框架会自动从代理透传的请求头中提取真实IP,避免用户伪造请求头造假IP。

第二步:设计MongoDB存储结构

推荐用两个集合实现,避免单文档存储内容过大:

  1. 文章集合articles新增views字段,类型为Number,默认值为0,存储文章累计浏览量
  2. 新建IP浏览记录集合article_views,字段设计如下:
    • articleId:关联的文章ID,加单字段索引
    • ipAddress:访问用户的IP地址
    • viewAt:访问时间,可用于定期清理过期记录
  3. 给article_views集合创建联合唯一索引,避免同一IP重复记录同一文章的访问:
    db.article_views.createIndex({ articleId: 1, ipAddress: 1 }, { unique: true })
    

第三步:实现中间件逻辑

以Express框架为例,中间件示例代码如下:

// 已提前定义好Mongoose模型:ArticleModel对应文章集合,ArticleViewModel对应浏览记录集合
const viewCountMiddleware = async (req, res, next) => {
  // 仅匹配动态文章请求,可根据自身路由规则调整判断条件
  if (req.method !== 'GET' || !req.path.startsWith('/articles/')) return next();

  const articleId = req.params.id;
  const userIp = req.ip; // 框架已开启代理信任,直接取真实IP

  try {
    // 尝试插入浏览记录,唯一索引冲突时会抛出错误
    await ArticleViewModel.create({
      articleId,
      ipAddress: userIp,
      viewAt: new Date()
    });
    // 插入成功说明是该IP首次访问当前文章,浏览量+1
    await ArticleModel.updateOne({ _id: articleId }, { $inc: { views: 1 } });
  } catch (err) {
    // 11000为MongoDB唯一索引冲突错误码,代表该IP已访问过,无需处理
    if (err.code !== 11000) {
      console.error('浏览量统计异常:', err);
    }
  }
  next();
};

用唯一索引冲突判断重复访问,比先查询再插入的逻辑性能更高,也天然避免了并发请求的竞态问题。

注意事项

  • 同一公网IP下的多个用户会被判定为同一个访问主体,这是无用户体系下用IP去重的固有缺陷,仅能实现近似统计
  • 可以定期清理3个月以上的浏览记录,降低存储成本,同时允许老用户隔一段时间后访问重新计数,更贴近真实浏览情况
  • 如果使用了云CDN服务,需要在CDN控制台配置开启真实IP透传,不同厂商的请求头名称可能有差异,按对应文档配置即可

内容的提问来源于stack exchange,提问作者user16832151

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 05:48:05