如何在React中存储已登录用户的观看视频记录?附播放器代码
解决已登录用户YouTube视频观看记录存储问题
嘿,针对你已登录用户观看视频记录的存储需求,结合你给出的VideoDetails组件,我整理了一套可落地的解决方案:
第一步:集成YouTube IFrame API监听播放行为
YouTube原生iframe不会主动暴露播放状态,所以我们得借助YouTube IFrame Player API来捕获用户的观看行为(比如视频开始播放、播放进度达标),这样才能准确记录有效观看记录。
修改你的组件,加入API加载和事件监听逻辑:
import React, { Component } from 'react'; class VideoDetails extends Component { constructor(props){ super(props); this.player = null; this.videoId = props.video?.id.videoId; this.hasRecorded = false; // 避免同一视频重复记录 } componentDidMount() { // 加载YouTube IFrame API if (!window.YT) { const tag = document.createElement('script'); tag.src = "https://www.youtube.com/iframe_api"; const firstScriptTag = document.getElementsByTagName('script')[0]; firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); // API加载完成后初始化播放器 window.onYouTubeIframeAPIReady = () => { this.initPlayer(); }; } else { this.initPlayer(); } } initPlayer() { this.player = new window.YT.Player('youtube-player', { videoId: this.videoId, events: { 'onProgress': this.onPlayerProgress // 监听播放进度,确保用户真的在看 } }); } onPlayerProgress = (event) => { // 当视频播放超过30%时记录(可根据需求调整阈值),且只记录一次 if (this.hasRecorded) return; const duration = event.target.getDuration(); const currentTime = event.target.getCurrentTime(); if (duration > 0 && currentTime / duration > 0.3) { this.saveWatchHistory(); this.hasRecorded = true; } } saveWatchHistory = () => { const { video } = this.props; if (!video) return; // 构造观看记录数据 const watchRecord = { userId: '替换为当前登录用户ID', // 从你的登录状态管理(如Context/Redux/localStorage)获取 videoId: video.id.videoId, videoTitle: video.snippet.title, watchedAt: new Date().toISOString(), progress: Math.round(this.player.getCurrentTime()) }; // 核心:发送到后端存储(已登录用户必须持久化到数据库) fetch('/api/user/watch-history', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${localStorage.getItem('authToken')}` // 替换为你的认证方式 }, body: JSON.stringify(watchRecord) }) .then(response => response.json()) .then(() => console.log('观看记录已成功保存')) .catch(err => console.error('保存观看记录失败:', err)); // 可选:本地缓存作为补充(比如离线时暂存,上线后同步) // const localHistory = JSON.parse(localStorage.getItem('localWatchHistory')) || []; // localHistory.unshift(watchRecord); // localStorage.setItem('localWatchHistory', JSON.stringify(localHistory.slice(0, 50))); } render(){ const video = this.props.video; if(!video) { return <div /> } return ( <div> <div> {/* 用带ID的div替代原生iframe,由YouTube API初始化播放器 */} <div id="youtube-player" className="Videoplayer"></div> </div> <div> <h2>{video.snippet.title}</h2> <div>{video.snippet.description}</div> </div> </div> ) } } export default VideoDetails;
第二步:后端存储配套逻辑
对于已登录用户,观看记录需要持久化到数据库,你需要在后端完成:
- 创建
user_watch_history表,字段建议包含:id(主键)、user_id(关联用户表)、video_id、video_title、watched_at、progress - 编写POST接口
/api/user/watch-history,验证用户身份后,将前端传来的记录存入数据库 - 可额外编写GET接口,供用户查询自己的观看历史
第三步:优化细节
- 避免重复记录:前端用
hasRecorded标记,后端可给user_id + video_id加唯一约束(或允许重复但保留最新记录) - 用户身份校验:确保
userId和认证令牌的正确性,避免未登录用户或伪造请求 - API加载容错:可添加API加载超时处理,避免因网络问题导致播放器初始化失败
内容的提问来源于stack exchange,提问作者Stonecold
相关产品推荐
相关产品推荐

