WebSocket 低版本浏览器兼容方案
在不支持 WebSocket 的浏览器中实现实时通信的降级方案
问题
如何在不支持 WebSocket 的低版本浏览器中实现实时通信功能?
解答
针对不支持 WebSocket 的浏览器,可以采用以下降级方案:
1. Adobe Flash Socket
利用 Flash 的 Socket 功能实现实时通信。需要用户安装 Flash 插件。
// 检测 Flash 支持
function hasFlash() {
try {
return Boolean(new ActiveXObject('ShockwaveFlash.ShockwaveFlash'));
} catch(e) {
return navigator.mimeTypes['application/x-shockwave-flash'] !== undefined;
}
}
2. ActiveX HTMLFile (IE)
IE 浏览器特有的方案,通过 ActiveX 控件创建隐藏的 iframe 实现长连接。
// IE 专用方案
if (window.ActiveXObject) {
var htmlfile = new ActiveXObject('htmlfile');
htmlfile.open();
htmlfile.write('<html><body></body></html>');
htmlfile.close();
}
3. 基于 multipart 编码的 XHR
服务器持续发送 multipart 响应,浏览器逐步接收数据。
var xhr = new XMLHttpRequest();
xhr.open('GET', '/stream', true);
xhr.setRequestHeader('Content-Type', 'multipart/x-mixed-replace');
xhr.onreadystatechange = function() {
if (xhr.readyState === 3) {
// 处理部分响应数据
console.log(xhr.responseText);
}
};
xhr.send();
4. 基于长轮询的 XHR
客户端发起请求后,服务器保持连接直到有新数据才返回,客户端收到响应后立即发起下一次请求。
function longPolling() {
var xhr = new XMLHttpRequest();
xhr.open('GET', '/poll', true);
xhr.onload = function() {
if (xhr.status === 200) {
// 处理数据
console.log(xhr.responseText);
// 立即发起下一次请求
longPolling();
}
};
xhr.onerror = function() {
// 错误后延迟重试
setTimeout(longPolling, 3000);
};
xhr.send();
}
关键点
- Flash Socket 需要插件支持,已逐渐被淘汰
- ActiveX HTMLFile 仅适用于 IE 浏览器
- multipart XHR 兼容性较好,但服务器实现复杂
- 长轮询是最通用的降级方案,但会增加服务器负载
- 建议使用 Socket.IO 等成熟库自动处理降级逻辑
目录