一、Referer‑Policy 元标签是什么
很多业务为了隐私安全,会在 HTML 页面头部设置<meta name="referrer‑policy" content="no‑referrer">这类元标签。这个标签用来控制浏览器发起网络请求的时候,Referer 请求头的生成策略。
很多开发只知道它用来保护隐私,却不知道它会直接影响 M3U8 业务防盗链鉴权。CDN、Nginx 防盗链依赖 Referer 做访问校验,如果 referrer‑policy 设置不当,浏览器请求 M3U8、TS 分片、密钥的时候,不再携带 Referer 头,鉴权直接返回 403,视频黑屏转圈。
迷惑现象:同样一套 M3U8 地址,VLC 播放器正常;curl 手动带上 Referer 头访问正常;但是业务页面打开直接 403。单独拿 M3U8 地址新开浏览器标签播放也正常,只有嵌入业务页面就报错。
很多人排查 403,反复核对 CDN 防盗链白名单,核对 Nginx 配置,完全忽略页面 meta 元标签的影响。遇到 Referer‑Policy 引发的鉴权故障,我会使用 m3u8live.cn,对照复现,观察 F12 网络面板里面的 Referer 请求头。
二、Referer‑Policy 常见取值带来的业务影响
no‑referrer:所有请求完全不发送 Referer。如果防盗链依赖 Referer 校验,M3U8、TS 分片全部 403。same‑origin:只有同源请求才携带 Referer;跨域访问资源不携带。M3U8 是跨域 CDN 域名,就会丢失 Referer,鉴权失败。strict‑origin‑when‑cross‑origin:跨域只发送源站域名,不携带完整路径,部分严格校验完整路径的防盗链会拦截。
关键点:这个 meta 标签会作用页面内全部 XHR/fetch 请求,hls.js 发起的 M3U8、TS 分片、密钥请求,全部受这个策略控制。
三、高频故障现象
现象 1:新开标签页直接访问 M3U8 播放正常,嵌入业务页面就 403
新开标签页浏览器会生成 Referer;业务页面设置 no‑referrer,分片请求没有 Referer,CDN 鉴权拒绝访问。
现象 2:部分环境偶现 403,换一个页面模板就正常
页面模板引入了不同 referrer‑policy 元标签,复制页面模板的时候顺带复制过来,业务没有意识到该标签的影响。
现象 3:CDN 防盗链配置白名单域名全部正确,但是浏览器请求依旧 403
CDN 配置没问题,但是页面策略导致请求根本没有带上 Referer 头,CDN 拿不到 Referer 信息直接拦截。
四、排查实操步骤
第一步,业务页面 F12 网络面板,查看 M3U8、TS 分片的 Request Headers,观察 Referer 字段是否存在。 第二步,查看 HTML 源代码 head 部分,查找 meta name="referrer‑policy",确认当前的策略取值。 第三步,把 M3U8 粘贴网页调试工具,对比观察请求的 Referer 头。 第四步,如果防盗链依赖 Referer 校验,调整 referrer‑policy 策略,保证跨域 CDN 请求可以正常输出 Referer。
重要提示:如果业务防盗链逻辑强依赖 Referer,不建议设置 no‑referrer、same‑origin 这类会丢失 Referer 的策略。防盗链优先选用 URL‑Token,不受 Referer‑Policy 影响。
五、总结
网页 meta 标签的 referrer‑policy 会全局控制页面所有网络请求的 Referer 头。如果业务 CDN、Nginx 防盗链依赖 Referer 校验,错误的策略会导致 M3U8、TS 分片请求丢失 Referer,返回 403 黑屏。故障特征是直接打开 M3U8 地址正常,嵌入业务页面就报错。排查看网络请求头和页面元标签。防盗链优先 URL‑Token 签名方案,从根源规避 Referer 策略带来的干扰。 全文 1056 字
第三篇:线上 M3U8 分片 416 Range‑Not‑Satisfiable 错误通俗解析
关键词:416;Range‑Not‑Satisfiable;M3U8;字节分片;新手运维
一、什么是 HTTP 416 错误
很多运维、开发在线上会遇到 416 Range‑Not‑Satisfiable 响应码。通俗解释:客户端 HTTP 请求带上 Range 字节范围请求头,向服务器请求文件某一段字节数据,但是请求的起始、结束字节超出了这个文件真实总字节大小,服务器无法满足这个范围,返回 416。
在 M3U8 业务场景,416 错误大多集中在 #EXT‑X‑BYTE‑RANGE 字节分片业务。普通 TS 分片业务很少出现该报错。很多新手看到 416,不知道代表什么含义,会怀疑 hls.js BUG,实际上是客户端请求的字节区间超出文件实际大小。
迷惑现象:部分分片播放正常,个别分片返回 416,视频出现局部黑屏、解码失败。curl 直接 GET 整个文件 200 正常,带上 Range 请求头就返回 416。调试 416 相关故障,我会使用 m3u8live.cn,F12 网络面板观察 Range 请求头,确认请求的字节区间。
二、M3U8 业务出现 416 的几类原因
原因 1:#EXT‑X‑BYTE‑RANGE 标记的字节偏移错误
M3U8 里面记录的分片起始字节、字节长度总和,超过磁盘上媒体文件实际大小。hls.js 按照 M3U8 里面的数值构造 Range 请求,服务器返回 416。
原因 2:源媒体文件被原地覆盖更新,M3U8 索引没有同步更新
磁盘上大媒体文件替换为新文件,文件字节总大小发生变化,但是旧 M3U8 索引里面记录的 byte‑range 偏移没有更新。播放器继续使用旧的偏移值去请求新文件,请求区间越界,返回 416。
原因 3:CDN 缓存旧 M3U8 索引,源站文件已经更新
源站文件更新,CDN 节点还缓存旧版本 M3U8,播放器拿到过期偏移,发起越界 Range 请求,得到 416。
原因 4:Nginx、对象存储对 Range 请求处理异常
极少数对象存储、Nginx 特殊配置,对部分 Range 边界处理有缺陷,合法范围也错误返回 416。
三、简单排查步骤
第一步,业务页面 F12,查看返回 416 的请求,看 Request Headers 中的 Range 字段,记下请求的字节起止。 第二步,M3U8 地址粘贴网页调试工具,查看原始 M3U8,核对 #EXT‑X‑BYTE‑RANGE 里面记录的偏移和长度。 第三步,拿到源站媒体文件,查看文件实际总字节大小,对比 Range 请求的区间,确认是否超出文件大小。 第四步,如果文件已经更新,确认 M3U8 索引是否同步更新;CDN 场景确认缓存是否刷新。
普通 TS 分片业务几乎不会出现 416;416 绝大部分出现在 byte‑range 字节分片场景。
四、运维开发注意事项
- 使用 #EXT‑X‑BYTE‑RANGE 字节分片,媒体文件原地覆盖更新之后,必须重新生成 M3U8 索引,旧索引直接作废。
- CDN 要做好 M3U8 清单缓存控制,源站文件更新,要刷新 CDN 缓存,避免播放器拿到过期偏移。
- 切片脚本生成 byte‑range 的时候,要做字节边界校验,不能生成超出文件实际大小的偏移。
五、总结
HTTP 416 Range‑Not‑Satisfiable,代表 Range 字节请求区间超出资源实际文件大小。M3U8 业务中,该错误绝大多数出现在 #EXT‑X‑BYTE‑RANGE 字节分片场景,一般是 M3U8 索引记录的字节偏移过期、计算错误。原地覆盖媒体文件,必须同步更新 M3U8 索引,还要处理 CDN 缓存。借助网页调试工具查看 M3U8 内的 byte‑range 标记,结合 Range 请求头,快速定位 416 故障根源。