Firefox与Safari中RTCPeerConnection不是构造函数的问题排查
针对你遇到的在Firefox 60.0.1和Safari中调用new RTCPeerConnection(config)抛出TypeError: RTCPeerConnection is not a constructor的问题,我整理了几个最可能的原因和对应的解决方法:
1. 浏览器前缀兼容问题
虽然MDN标注Firefox从v22开始支持RTCPeerConnection,但在v44之前的版本,Firefox使用的是带前缀的mozRTCPeerConnection构造函数;而Safari在早期版本(比如v11及以前)则使用webkitRTCPeerConnection。你的代码可能没有处理这些前缀,导致旧版浏览器找不到标准构造函数。
解决方法:添加一个兼容层来获取正确的构造函数:
// 兼容不同浏览器的RTCPeerConnection前缀 const getRTCPeerConnection = () => { return window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection; }; const RTCPeerConnection = getRTCPeerConnection(); if (!RTCPeerConnection) { alert('当前浏览器不支持WebRTC功能'); // 这里可以做降级处理 }
之后再用new RTCPeerConnection(config)初始化连接即可。
2. 非安全上下文限制
WebRTC API在非安全上下文(即HTTP协议,除了localhost)中会被浏览器禁用,Firefox和Safari对这个限制的执行比Chrome更严格。如果你的Web应用是通过HTTP访问的(比如直接访问树莓派的IP地址),就会触发这个问题。
解决方法:
- 测试阶段可以通过
localhost或127.0.0.1访问页面,浏览器会把localhost视为安全上下文; - 生产环境配置HTTPS:可以给树莓派的服务器配置自签名证书(虽然浏览器会提示不安全,但可以手动信任),或者使用合法的SSL证书。
3. RTCPeerConnection配置参数格式问题
旧版浏览器对RTCPeerConnection的配置参数格式要求更严格,比如iceServers字段,早期Firefox不支持直接传入字符串数组,必须是包含urls属性的对象数组。
比如,不要这样写:
const config = { iceServers: ['stun:stun.l.google.com:19302'] };
改成兼容格式:
const config = { iceServers: [ { urls: 'stun:stun.l.google.com:19302' } ] };
4. UV4L Demo的协商逻辑适配问题
UV4L的Demo代码可能是针对Chrome优化的,在Firefox和Safari中,SDP协商或WebSocket交互的步骤可能存在兼容性问题。比如:
- ICE Candidate的收集时机差异;
- SDP的格式解析差异;
- WebSocket消息的处理顺序。
解决方法:打开浏览器的开发者工具(控制台),查看是否有其他相关错误信息(比如SDP解析失败、WebSocket连接异常),然后针对性调整协商逻辑。比如确保在收到WebSocket的offer后再创建answer,或者正确处理ICE candidate的添加。
内容的提问来源于stack exchange,提问作者Carles Araguz

