视频传输故障需交叉验证MediaError.code、网络状态和浏览器能力:code=2需查HTTP状态码,code=3/4非传输问题;Network面板看状态码、Content-Type及Range支持;HEAD预检可快速定位异常类型;stalled+buffered可捕获静默失败。

视频出错时不能只看控制台报错数字,关键要结合 MediaError.code、网络请求状态、浏览器能力三者交叉验证,才能准确定位是传输链路哪一环断了。
看 MediaError.code 判定错误大类
video.error?.code 是第一线索,但它只在加载阶段触发,必须配合其他信号判断真实原因:
-
code = 1(MEDIA_ERR_ABORTED):用户主动中断,比如跳转页面、调用
load()后立刻pause()。这类不反映传输问题,无需排查网络 - code = 2(MEDIA_ERR_NETWORK):最可能指向传输故障。但需进一步确认是 404、403、CORS 还是连接超时——这得看 Network 面板里的 HTTP 状态码
- code = 3(MEDIA_ERR_DECODE):文件已完整下载,说明传输成功,问题在解码层(如 H.265 在 Safari 上不支持),不属于传输故障
-
code = 4(MEDIA_ERR_SRC_NOT_SUPPORTED):所有
<source>格式都不被识别,和传输无关,是格式声明或 MIME 类型配置错误
查 Network 面板确认传输实际状态
仅靠 code=2 不足以定位传输故障,必须打开开发者工具的 Network 面板,筛选视频请求,重点看三项:
- HTTP 状态码:404 表示路径错误或文件未部署;403 多因服务器权限设置或 CDN 防火墙拦截;0 状态码常见于广告屏蔽插件阻断域名或 CORS 预检失败
-
Response Headers 中的 Content-Type:必须是
video/mp4、video/webm等标准类型。若返回text/html或application/octet-stream,说明服务器 MIME 映射缺失 -
是否支持 Range 请求:MP4 播放依赖字节范围请求获取 moov atom。若响应头中没有
Accept-Ranges: bytes,且视频卡在“加载中”,大概率是 Nginx/Apache 未启用range支持
用 fetch + HEAD 预检快速区分传输异常类型
在 error 事件里不直接重试,而是先轻量探测资源可达性:
立即学习“前端免费学习笔记(深入)”;
- 对视频 URL 发起
fetch(url, { method: 'HEAD' }) - 若返回 404 或 403,说明路径或权限问题,提示“视频地址无效,请检查链接”
- 若请求超时或抛网络错误,更可能是弱网或 DNS 故障,提示“网络不稳定,正在重试…”并自动重载
- 若返回 200 但
Content-Type不匹配,则归为服务端配置问题,不引导用户重试,而是上报运维
排除静默传输失败:监听 stalled + buffered 验证首帧加载
有些传输问题不会触发 error 事件,比如首帧元数据迟迟不回。这时需监听 stalled 并检查缓冲区:
- 当
stalled触发且video.buffered.length === 0,持续超 3 秒,基本可判定首帧未传到,属于传输卡顿 - 此时即使
networkState === HTMLMediaElement.NETWORK_LOADING,也应按网络故障处理,给出重试入口 - 特别注意 iOS Safari:若
readyState === 0且paused === true,很可能是 autoplay 被静音策略拦截,不是传输问题,需单独提示“请手动点击播放”



















