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

Laravel中如何通过Ajax持续存储视频播放进度至数据库?

嘿,我来帮你一步步搞定这个视频续看功能!你已经搭好了监听播放状态、获取播放时长的基础代码,接下来只需要把这些数据通过Ajax传给Laravel后端,再更新到users表的watch_history字段就行。下面是具体实现步骤:

一、前端代码修改(Lesson_video.blade.php)

首先要把Blade里的lesson_id传给JS,然后在你的performaction函数里加入Ajax请求,把数据发给后端:

<!-- 先确保你的页面<head>里有CSRF令牌(Laravel默认模板一般已经包含,没有的话加上) -->
<meta name="csrf-token" content="{{ csrf_token() }}">

<script>
var vid = document.getElementById("player");
// 从Blade模板获取当前课程ID
let lessonId = {{ $lesson->id }};

$(function() {
    var timeout;
    $("#player").on("playing pause", function(e) {
        var v = this
        clearTimeout(timeout)
        performaction(v.currentTime, v.duration)
        if (e.type === "playing") {
            timeout = setInterval(function() {
                performaction(v.currentTime, v.duration)
            }, 3000) // 可以根据需求调整间隔,比如5秒减少请求频率
        }
    })

    function performaction(currentTime, duration) {
        console.log(`当前播放时长: ${currentTime}, 课程ID: ${lessonId}`);

        // 发送Ajax请求到后端
        $.ajax({
            url: "{{ route('watch-history.update') }}", // 后端命名路由
            method: "POST",
            data: {
                lesson_id: lessonId,
                current_time: Math.round(currentTime), // 取整存储,避免小数精度问题
                duration: duration
            },
            headers: {
                // 带上CSRF令牌,Laravel会验证POST请求的合法性
                'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
            },
            success: function(response) {
                console.log("观看历史更新成功:", response);
            },
            error: function(xhr) {
                console.error("更新失败:", xhr.responseText);
            }
        });
    }
})
</script>

二、后端路由配置(routes/web.php)

添加一个带登录验证的POST路由,指向我们即将创建的控制器方法:

use App\Http\Controllers\WatchHistoryController;

Route::post('/watch-history/update', [WatchHistoryController::class, 'update'])
    ->name('watch-history.update')
    ->middleware('auth'); // 确保只有登录用户才能更新

三、创建并编写控制器

先通过Artisan命令生成控制器:

php artisan make:controller WatchHistoryController

然后在app/Http/Controllers/WatchHistoryController.php里编写update方法,处理前端传过来的数据:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class WatchHistoryController extends Controller
{
    public function update(Request $request)
    {
        // 验证请求数据的合法性
        $request->validate([
            'lesson_id' => 'required|integer',
            'current_time' => 'required|numeric|min:0',
            'duration' => 'required|numeric|min:0'
        ]);

        // 获取当前登录用户
        $user = Auth::user();

        // 取出用户的观看历史,为空则初始化空数组
        $watchHistory = $user->watch_history ?? [];

        // 查找是否已存在该课程的观看记录
        $lessonIndex = array_search($request->lesson_id, array_column($watchHistory, 'lesson_id'));

        if ($lessonIndex !== false) {
            // 存在则更新当前播放时长和总时长
            $watchHistory[$lessonIndex]['current_time'] = $request->current_time;
            $watchHistory[$lessonIndex]['duration'] = $request->duration;
        } else {
            // 不存在则添加新记录
            $watchHistory[] = [
                'lesson_id' => $request->lesson_id,
                'current_time' => $request->current_time,
                'duration' => $request->duration
            ];
        }

        // 更新用户的watch_history字段
        $user->update([
            'watch_history' => $watchHistory
        ]);

        // 返回成功响应给前端
        return response()->json([
            'status' => 'success',
            'message' => '观看历史已更新',
            'data' => $watchHistory
        ]);
    }
}

四、数据库字段与模型配置

  1. 添加watch_history字段
    如果你的users表还没有这个字段,生成迁移:
php artisan make:migration add_watch_history_to_users_table

打开迁移文件,设置字段为JSON类型:

public function up()
{
    Schema::table('users', function (Blueprint $table) {
        $table->json('watch_history')->nullable();
    });
}

public function down()
{
    Schema::table('users', function (Blueprint $table) {
        $table->dropColumn('watch_history');
    });
}

运行迁移:

php artisan migrate
  1. User模型配置
    在app/Models/User.php里添加字段映射和可填充设置,让Laravel自动把JSON转成数组:
class User extends Authenticatable
{
    // ...其他代码

    // 把JSON字段自动转为数组
    protected $casts = [
        'email_verified_at' => 'datetime',
        'watch_history' => 'array'
    ];

    // 允许批量赋值的字段
    protected $fillable = [
        'name',
        'email',
        'password',
        'watch_history' // 新增这个
    ];
}

一些优化建议

  • 你当前是每3秒发送一次请求,可根据需求调整间隔(比如5秒),或者只在用户暂停播放、播放进度变化超过一定阈值时发送,减少服务器压力;
  • 测试时可以查看Laravel日志(storage/logs/laravel.log)或直接查看数据库,确认数据是否正确存储;
  • 后续做续看功能时,只需要从用户的watch_history数组里找到对应lesson_id的current_time,设置给视频播放器即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 14:57:38