HTML5原生不支持RTSP,video标签加crossorigin无效;跨域问题实际发生在代理服务(如Nginx转FLV/HLS)或前端JS库(如flv.js)请求HTTP流地址时,需服务端正确配置CORS响应头。

HTML5 原生不支持 RTSP,所以不存在“HTML5 播放 RTSP 跨域”这回事——你遇到的其实是代理转发或转封装环节的跨域问题。
为什么 video 标签加 crossorigin 无效
RTSP 是基于 TCP/UDP 的实时流协议,而 HTML5 只支持 HTTP(S) 协议的 mp4、webm、hls(需 MSE)、dash 等。浏览器根本不会尝试用 video 标签去发起 RTSP 请求,所以设置 crossorigin="anonymous" 或配 CORS 头毫无意义。
- 常见错误现象:控制台报
Failed to load resource: net::ERR_CONNECTION_REFUSED或直接无响应,不是 CORS 错误,而是协议不被支持 - 真正走网络请求的是你后端代理服务(如 Nginx、Node.js、ffmpeg + http-server)或前端 WebRTC/WS 封装层
- 如果你在用
flv.js、hls.js或自研 WebSocket 拉流,那跨域发生在它们请求/flv、/stream.m3u8或ws://地址时
Nginx 代理 RTSP 转 FLV/HLS 时如何配跨域
典型链路是:RTSP → ffmpeg 推流到 Nginx-rtmp-module → Nginx 暴露 HTTP FLV 或 HLS 接口 → 前端 JS 加载。跨域实际发生在前端请求 Nginx 的 http://your-domain.com/live/test.flv 这类地址时。
- 必须在 Nginx 的
location块中显式添加 CORS 响应头,不能只靠add_header在 server 级别——FLV 流是 chunked,部分客户端会忽略 server 级 header - 示例配置(针对 FLV):
location /live {
flv;
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'false';
add_header 'Access-Control-Allow-Methods' 'GET, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
}
- 若用 HLS,同理配在
location ~ \.m3u8$和location ~ \.ts$下;注意.ts文件也要透出 CORS 头,否则 hls.js 会卡住 - 生产环境避免用
*,改用具体域名,且Access-Control-Allow-Credentials: true时Origin不能为*
前端用 flv.js 拉流时的跨域关键点
flv.js 内部用 fetch 或 XMLHttpRequest 拉 FLV 分片,因此受浏览器同源策略约束。它不走 的原生逻辑,所以跨域必须由服务端响应头解决。
立即学习“前端免费学习笔记(深入)”;
- 确认你请求的 URL 是 HTTP(不是 RTSP),例如
http://192.168.1.100:8080/live/test.flv - 用浏览器 DevTools 的 Network 面板检查该请求的响应头,确认包含
Access-Control-Allow-Origin - 如果用了
withCredentials: true(比如带 cookie 认证),服务端必须返回Access-Control-Allow-Credentials: true,且前端FlvPlayer初始化时要传enableWorker: false, enableStashBuffer: false, withCredentials: true - 不要试图在 JS 里伪造 header——
fetch的mode: 'no-cors'会让响应变成 opaque,flv.js无法读取二进制流
绕过跨域的替代方案(不推荐但有时不得不选)
当无法控制服务端响应头(比如调用第三方 RTSP 服务且对方不配合),只能从架构层面规避浏览器限制。
- 用
iframe嵌入一个同源的中转页,该页面内嵌flv.js并通过postMessage向父页传递状态——本质是把跨域请求放在 iframe 里完成 - 前端完全放弃浏览器播放器,改用 Electron 或 Tauri 打包,用 Node.js 子进程跑
ffmpeg -i rtsp://... -f flv -再通过本地 HTTP Server 提供流 - WebRTC 方案:用
mediasoup或janus-gateway接入 RTSP,再以RTCPeerConnection输出——WebRTC 不受同源策略限制,但开发成本高、信令复杂
最容易被忽略的一点:很多开发者花半天调试 Access-Control-Allow-Origin,却没发现 ffmpeg 推流根本没成功,Nginx-rtmp-module 的 live 应用压根没收到帧——先用 ffplay http://localhost:8080/live/test.flv 在服务端本地验证流是否可达,再谈跨域。










