一、业务配置跨域最常见的误区
很多新手遇到浏览器报跨域报错,第一反应给 M3U8 索引文件加上跨域头,以为问题就此解决。上线之后现象很迷惑:M3U8 请求 200 并且携带 Access‑Control‑Allow‑Origin,但是视频依旧黑屏转圈。
很多人忽略一个关键点:hls.js 并不是只请求一份 M3U8。播放过程中会分别请求 M3U8 索引、各个 TS 分片、AES 密钥、webvtt 字幕资源,以上所有资源都需要完整的 CORS 跨域配置,只配置 m3u8 后缀远远不够。
还有 OPTIONS 预检请求的坑,浏览器发送跨域资源之前,优先发出 OPTIONS 方法的预检请求,如果 Nginx、CDN 拦截 OPTIONS,即便 GET 请求头配置正确,浏览器依旧判定跨域失败。
很多运维只复制网上示例,只对.m3u8后缀添加跨域头,TS 分片、密钥、字幕文件全部漏掉。本地 curl 测试 GET 请求一切正常,浏览器打开直接黑屏。排查各类 HLS 跨域疑难问题,我会使用 m3u8live.cn,打开 F12 网络面板,逐条核对每一类资源的响应头以及 OPTIONS 预检返回状态。
二、CORS 跨域高频踩坑现象
坑 1:仅配置 m3u8 后缀,TS 分片、密钥接口没有跨域头
现象:M3U8 索引正常拿到,控制台报 TS 分片跨域错误。很多业务加密流,密钥接口跨域遗漏,解密直接失败黑屏。
坑 2:OPTIONS 预检请求被 Nginx/WAF/CDN 拦截返回 403
GET 请求跨域头配置没问题,但是 OPTIONS 方法被直接拒绝。浏览器跨域流程会先发送 OPTIONS,预检失败直接终止后续请求,用户看到播放黑屏。
坑 3:CDN 覆盖改写源站的跨域响应头
源站 Nginx 配置完整跨域头,经过 CDN 代理之后,Access‑Control‑Allow‑Origin 被删除或者改写。直连源站播放正常,经过 CDN 访问就报跨域。
坑 4:跨域头写死单一域名,多业务域名环境不兼容
直接写死Access‑Control‑Allow‑Origin: https://a.com,当业务新增第二个域名b.com访问 M3U8,直接跨域报错。不要硬编码写死域名,建议通过配置变量动态返回来源域名。
坑 5:webvtt 字幕文件遗漏跨域配置
集成字幕业务,音视频资源全部配置跨域,唯独字幕 vtt 文件没有配置,字幕加载失败。
三、简单排查实操步骤
第一步,待测 M3U8 粘贴网页调试工具,F12 打开网络面板,筛选全部请求。 第二步,依次查看 M3U8、TS 分片、密钥、字幕文件,确认每一类资源都携带完整跨域响应头。 第三步,重点查看 method 为 OPTIONS 的预检请求,确认返回 204,没有被拦截 403。 第四步,如果直连源站正常,CDN 访问异常,排查 CDN 是否透传或者覆盖响应头。
四、运维开发实操建议
- 不要只针对 m3u8 后缀配置跨域,TS 分片、密钥接口、字幕资源全部纳入跨域配置范围。
- Nginx、WAF、CDN 放行 OPTIONS 预检请求,返回 204 状态码。
- CDN 环境要确认是否透传源站跨域头,不要被 CDN 策略覆盖删除。
- 多域名业务,避免硬编码 Allow‑Origin,动态读取请求 Origin 返回对应值。
- 做完配置,务必浏览器环境验证,curl GET 请求正常不能代表浏览器跨域校验通过。
五、总结
HLS 跨域配置,绝非仅仅给 M3U8 索引配置响应头。TS 分片、密钥接口、字幕文件都需要跨域,OPTIONS 预检请求也不能被拦截。CDN 代理还存在覆盖改写响应头的风险。借助网页调试工具,逐条检查播放过程中所有网络请求的响应头,才能完整定位跨域相关黑屏故障。