如何解决AWS部署后视频无法显示及DOMException错误问题
本地正常的视频悬停播放功能部署到AWS后无法加载的问题解决
问题概述
本地环境中,通过onMouseOver和onMouseOut事件控制视频播放/暂停完全正常,但部署到AWS后视频无法显示,控制台抛出错误:
Uncaught (in promise) DOMException: The element has no supported sources.
视频已上传至GitHub,排除文件本身问题。相关React组件代码如下:
interface ICanvasProps { canvas: { name: string; src: any; } } export function Canvas(props: ICanvasProps) { const { canvas } = props return ( { canvas.map((canva) => { return ( <div key={canva.name} className='card'> <video preload={'auto'} autoPlay loop onLoad={()=>{"I am loaded"}} //@ts-ignore onMouseOver = { (event) => event.target.play() } //@ts-ignore onMouseOut = { (event) => event.target.pause() } style={{ width: '100%', borderRadius:"10px" }} src={canva.src}></video> </div> ) }) } </div> ) }
已排查event.target相关问题,怀疑浏览器无法在视频显示前完成加载,但因为视频是通过数组遍历生成的,不知道怎么处理加载逻辑。
解决方案
1. 检查跨域与AWS配置
AWS部署的网站请求GitHub托管的视频可能触发跨域限制:
- 确认GitHub Pages(若用其托管视频)已开启跨域允许,或AWS S3/CloudFront配置了正确的CORS规则,允许请求GitHub资源。
- 确保
canva.src是完整的可直接访问的视频URL,而非本地相对路径。
2. 修复视频加载与播放逻辑
原代码依赖event.target且未处理视频加载状态,改用useRef管理视频元素,统一处理加载与播放:
import { useRef } from 'react'; interface ICanvasProps { canvas: Array<{ name: string; src: string; }>; } export function Canvas(props: ICanvasProps) { const { canvas } = props; const videoRefs = useRef<HTMLVideoElement[]>([]); const handleMouseOver = (index: number) => { const video = videoRefs.current[index]; if (!video) return; // 视频已加载到可播放状态 if (video.readyState >= 2) { video.play().catch(err => console.error('播放失败:', err)); } else { // 等待加载完成后播放 video.addEventListener('canplaythrough', () => { video.play().catch(err => console.error('播放失败:', err)); }, { once: true }); } }; const handleMouseOut = (index: number) => { const video = videoRefs.current[index]; if (video) video.pause(); }; return ( <div> {canvas.map((canva, index) => ( <div key={canva.name} className='card'> <video ref={el => videoRefs.current[index] = el!} preload="auto" loop style={{ width: '100%', borderRadius: "10px" }} src={canva.src} onMouseOver={() => handleMouseOver(index)} onMouseOut={() => handleMouseOut(index)} /> </div> ))} </div> ); }
- 用
useRef数组存储每个视频元素,避免event.target的类型与不确定性问题。 - 通过
readyState判断视频加载状态,未加载完成则绑定canplaythrough事件等待加载后播放。 - 给
play()添加catch捕获错误,便于排查播放失败原因。
3. 验证视频格式兼容性
确保视频为MP4(H.264编码)这类全浏览器兼容格式,避免使用WebM等支持有限的格式。可直接在浏览器地址栏访问视频URL,确认资源可正常播放。
4. 清除AWS缓存
若部署过旧版本,CloudFront可能缓存了错误路径:
- 手动清除CloudFront缓存。
- 给视频URL添加版本参数(如
canva.src + '?v=1'),强制浏览器加载最新资源。
内容的提问来源于stack exchange,提问作者hitmaker808
相关产品推荐
相关产品推荐

