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

如何在Laravel 9中使用Ajax实时存储自增计数器的数值?

Laravel 9自增计数器持久化实现思路

下面是几种解决计数器刷新重置问题的可行方案,可根据你的使用场景(单用户/多用户、是否需要防篡改)选择:

方案一:定时向后端API同步计数器值

适合单用户或对实时性要求不高的多用户场景,前端定期将当前计数器值提交到后端更新数据库。

实现步骤:

  1. 添加后端路由与控制器方法
    在routes/web.php中添加POST路由:

    Route::post('/update-natality-counter', [NatalityController::class, 'updateCounter']);
    

    在对应控制器中编写更新逻辑(使用原子增量避免并发冲突):

    public function updateCounter(Request $request)
    {
        $request->validate(['counter' => 'required|integer']);
        $natality = Natality::first();
        // 计算前端与后端的差值,仅增量更新
        $increment = $request->counter - $natality->number;
        if ($increment > 0) {
            $natality->increment('number', $increment);
        }
        return response()->json(['success' => true]);
    }
    
  2. 修改前端JS代码
    保留原自增逻辑,新增定时同步的请求:

    var counter = {{ $number}};
    var counterNode = document.getElementById('counter');
    counterNode.innerHTML = counter;
    
    // 每秒自增2
    setInterval(function() {
        counter += 2;
        counterNode.innerHTML = counter;
    }, 1000);
    
    // 每30秒同步一次到后端
    setInterval(function() {
        fetch('/update-natality-counter', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content
            },
            body: JSON.stringify({ counter: counter })
        });
    }, 30000);
    

方案二:WebSockets实时同步(多用户场景)

如果有多个用户同时访问页面,需要所有用户看到一致的计数器数值,用Laravel Echo配合WebSockets实现实时广播。

实现步骤:

  1. 配置Laravel Echo与WebSocket服务
    按照Laravel文档配置好Echo和Pusher(或自建Socket服务器)。

  2. 定义广播事件
    创建一个NatalityCounterUpdated事件,用于广播更新后的计数器值。

  3. 前端逻辑调整

    • 前端自增时触发广播事件,后端监听并更新数据库,再广播最新值给所有客户端。
    • 客户端监听广播事件,同步更新本地计数器:
      // 初始化计数器
      var counter = {{ $number}};
      var counterNode = document.getElementById('counter');
      counterNode.innerHTML = counter;
      
      // 监听广播事件
      Echo.channel('natality-counter')
          .listen('NatalityCounterUpdated', (e) => {
              counter = e.counter;
              counterNode.innerHTML = counter;
          });
      
      // 触发自增与广播
      setInterval(function() {
          counter += 2;
          fetch('/trigger-counter-update', {
              method: 'POST',
              headers: {
                  'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content
              }
          });
      }, 1000);
      

方案三:前端本地存储+后端定时同步

适合单用户使用,先通过localStorage保存当前计数器值,页面加载时优先读取本地值,再定期同步到后端。

实现代码:

// 页面加载时优先读取本地存储
var savedCounter = localStorage.getItem('natalityCounter');
var counter = savedCounter ? parseInt(savedCounter) : {{ $number}};
var counterNode = document.getElementById('counter');
counterNode.innerHTML = counter;

// 每秒自增并保存到本地存储
setInterval(function() {
    counter += 2;
    counterNode.innerHTML = counter;
    localStorage.setItem('natalityCounter', counter);
}, 1000);

// 每分钟同步到后端
setInterval(function() {
    fetch('/update-natality-counter', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content
        },
        body: JSON.stringify({ counter: counter })
    });
}, 60000);

方案四:后端定时任务自增(防篡改场景)

如果需要严格控制计数器数值,避免前端篡改,将自增逻辑放到后端定时任务中,前端仅负责展示最新值。

实现步骤:

  1. 添加后端定时任务
    在app/Console/Kernel.php中定义每分钟自增120(对应前端每秒加2的速率):

    protected function schedule(Schedule $schedule)
    {
        $schedule->call(function () {
            Natality::first()->increment('number', 120);
        })->everyMinute();
    }
    
  2. 前端定时拉取最新值

    var counterNode = document.getElementById('counter');
    
    // 初始加载获取数值
    function fetchCounter() {
        fetch('/get-natality-counter')
            .then(res => res.json())
            .then(data => {
                counterNode.innerHTML = data.counter;
            });
    }
    
    fetchCounter();
    // 每10秒刷新一次
    setInterval(fetchCounter, 10000);
    
  3. 添加获取计数器的路由

    Route::get('/get-natality-counter', [NatalityController::class, 'getCounter']);
    

    控制器方法:

    public function getCounter()
    {
        return response()->json(['counter' => Natality::first()->number]);
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 05:41:19