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

Laravel increment实现浏览量计数偶发多累加问题求助

Laravel increment浏览量异常累加问题排查及修复方案

问题原因

1. 作用域(Scope)使用不符合规范

Laravel的Scope设计初衷是复用查询构造逻辑,不应该在Scope中直接执行increment这类写操作。你当前的写法虽然大多数场景可以运行,但如果后续存在链式调用该Scope的场景,很容易触发重复执行计数逻辑的问题。

2. 浏览器预加载机制触发重复请求

现在主流浏览器都内置了链接预加载功能,用户hover到链接上时浏览器会提前发起请求预加载页面内容,如果用户随后正式点击访问,就会产生两次有效请求,导致浏览量累加2次。

3. 业务逻辑导致重复请求

可能的场景包括:

  • 路由存在301/302重定向,跳转前后的两次请求都执行了计数逻辑
  • 页面存在无效资源路径(如空src的img标签),错误触发了当前页面路由的请求
  • 前端逻辑异常重复发起了页面请求

修复方案

第一步:修正模型方法定义

删掉原来的Scope写法,改为普通的模型实例方法:

// app/Models/Article.php
public function incrementViewCount()
{
    return $this->increment('view', 1);
}

第二步:优化控制器计数逻辑,增加幂等判断

可以通过Session/Cookie标记用户访问状态,同一用户24小时内访问同一篇内容仅计数一次,同时排除浏览器预加载请求:

// 控制器逻辑
public function quoteBySlug($slug)
{
    // 直接用firstOrFail简化404判断
    $quote = Article::bySlug($slug)->firstOrFail();
    
    // 排除浏览器预加载请求
    $isPrefetch = request()->hasHeader('Purpose') && request()->header('Purpose') === 'prefetch'
        || request()->hasHeader('X-Moz') && request()->header('X-Moz') === 'prefetch';
    
    // 验证用户是否已访问过该内容
    $viewedKey = 'viewed_article_' . $quote->id;
    if (!$isPrefetch && !session()->has($viewedKey)) {
        $quote->incrementViewCount();
        // 访问标记24小时内有效
        session()->put($viewedKey, now()->timestamp);
        session()->expireAt($viewedKey, now()->addDay());
    }
            
    return view('pages/quote/quote-detailed')->with('quote', $quote);
}

第三步:排查业务侧异常

  • 检查当前路由是否存在重定向配置
  • 检查前端页面是否存在重复发起请求的逻辑,或者路径为空的资源标签

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 23:45:05