WebSocket兼容到低版本浏览器

就目前而言,WebSocket是最好的Web通信解决方案了。但是IE从10才开始兼容它,对于目前大量IE8存在的市场,原生的WebSocket显然不太实用,我们需要低版本兼容的解决方案。于是我模拟WebSocket在浏览器上的行为,用AS3写了个兼容的版本。 
内容有点多,这篇只把演示给搞定,至于AS的源码就丢到下一篇了。下面是效果图: 

演示下载地址: WebSocket兼容到低版本浏览器(演示实例) 
页面代码比较简单,用法和正常的WebSocket基本一样,只是引用了WebSocket.js这个文件来兼容低版本浏览器。当然还有个WebSocket.swf需要放在与页面相同的目录下。 
<script src="WebSocket.js"></script>
<script>
onload=function(){
  var ws=new WebSocket("ws://127.0.0.1:8000");
  ws.onopen=function(){
    //握手成功
    send.removeAttribute("disabled");
    send.value="发送";
  };
  ws.onmessage=function(e){
    //收到消息,放到页面上
    var dl,dt,dd,o=eval("("+e.data+")");
    dl=document.createElement("dl");
    dt=document.createElement("dt");
    dd=document.createElement("dd");
    dt.innerHTML=o.client;
    dd.appendChild(document.createTextNode(o.content));
    dl.appendChild(dt);
    dl.appendChild(dd);
    wall.appendChild(dl);
    wall.scrollTop=1E8; //滚动条移到底部
  };
  send.onclick=function(){
    //发送消息
    if(!message.value)return alert("请输入内容");
    ws.send(message.value);
    message.value="";
  };
};
</script>
<style>
dl {margin:3px 10px;font:14px/20px Consolas,微软雅黑;}
dt {color:blue;}
#wall {
  border:1px solid #CCC;width:200px;height:200px;
  overflow-y:auto;margin-bottom:10px;
}
</style>
<div id="wall"></div>
<input id="message" />
<input type="button" value="连接中···" id="send" disabled />
 服务器程序使用NodeJS代码,随手写的聊天室功能,仅仅为了实现功能而已,作为演示代码不要吐槽考虑的不够周全。里面的 decodeDataFrame 和 encodeDataFrame 在之前的文章中有出现过,这里就不贴出来了。由于需要兼容AS版,所以服务器程序需要比普通的WebSocket多一个AS的域安全验证的步骤。这是关键所在,如果使用现成的WebSocket库之类的东西可能得稍微修改源码才能兼容AS版。 
var crypto=require('crypto');
var fs=require('fs');
var WS='258EAFA5-E914-47DA-95CA-C5AB0DC85B11';

var pool=[]; //连接池

require('net').createServer(function(o){
  var key;
  o.on('data',function(e){
    if(!key){
      var data=e.toString();
      //Flash握手
      if(data=='<policy-file-request/>\0')
        return fs.readFile('policy.txt',function(err,data){
          o.write(data+'\0');
        });
      //WebSocket握手
      if(key=data.match(/Sec-WebSocket-Key: (.+)|$/)[1])
        key=crypto.createHash('sha1').update(key+WS).digest('base64'),
        o.write([
          'HTTP/1.1 101 Switching Protocols',
          'Upgrade: websocket',
          'Connection: Upgrade',
          'Sec-WebSocket-Accept: '+key
        ].join('\r\n')+'\r\n\r\n');
    }else{
      //解析数据
      var frame=decodeDataFrame(e);
      //文本帧
      if(frame.Opcode==1){
        //转义数据
        var content=frame.PayloadData.replace(/\W/g,function(e){
          e=e.charCodeAt(0).toString(16);
          if(e.length==3)e='0'+e;
          return '\\'+(e.length>2?'u':'x')+e;
        }),client=o.remoteAddress+":"+o.remotePort,buffer;
        //包装成JSON格式,并做成一个数据帧
        buffer=encodeDataFrame({
          FIN:1,Opcode:1,
          PayloadData:'{"client":"'+client+'","content":"'+content+'"}'
        });
        //对所有连接广播数据
        for(i=0;i<pool.length;i++)pool[i].write(buffer);
      };
    };
  });
  //断开时从连接池中移除
  o.on("close",function(){
    for(i=0;i<pool.length;i++)if(pool[i]==o)pool.splice(i,1);
  });
  //放入连接池中
  pool.push(o);
}).listen(8000);
 Flash握手就是AS的域安全验证,这个在之前的文章“ 使用AS直接与服务器TCP通信 ”中有详细的说过,其实就是加载一个策略文件给它。把这个过程嵌入到WebSocket的握手之前就行。 
WebSocket.js的代码就不贴出来说明了。它负责构造一个类似原生WebSocket的接口的功能,里面会对不兼容WebSocket的浏览器加载WebSocket.swf来使之兼容。 
这个程序也是最近刚写的,存在漏洞在所难免,如果实用的话以后将慢慢完善它。

时间: 2024-09-13 04:52:54

WebSocket兼容到低版本浏览器的相关文章

websocket 如何兼容低版本浏览器?

问题描述 websocket 如何兼容低版本浏览器? [WebSocket] debug enabled [WebSocket] policy file: xmlsocket://211.95.3.194:843 [WebSocket] cannot connect to Web Socket server at ws://211.95.3.194:11113/demo01/MyHtml.html?message_to=&message_me= (SecurityError: Error #20

ES6 + Webpack + React + Babel 如何在低版本浏览器上愉快的玩耍(上)

起因 某天,某测试说:"这个页面在 IE8 下白屏,9也白.." 某前端开发: 吭哧吭哧...一上午的时间就过去了,搞定了. 第二天,某测试说:"IE 又白了.." 某前端开发: 吭哧吭哧...谁用的 Object.assign,出来我保证削不屎你. 原谅我不禁又黑了一把 IE. 有人可能会想,都要淘汰了,还有什么好讲的? 也许几年后,确实没用了,但目前我们的系统还是要对 ie8+ 做兼容,因为确实还有个别用户,尽管他没朋友... 记录下本次在 IE 下踩得坑,让后

ES6 + Webpack + React + Babel 如何在低版本浏览器上愉快的玩耍(下)

回顾 起因 某天,某测试说:"这个页面在 IE8 下白屏,9也白.." 某前端开发: 吭哧吭哧...一上午的时间就过去了,搞定了. 第二天,某测试说:"IE 又白了.." 某前端开发: 嘿咻嘿咻...谁用的 Object.assign,出来我保证削不屎你. 在上篇,我们主要抛出了两个问题,并给出了第一个问题的解决方案. 1. SCRIPT5007: 无法获取属性 xxx 的值,对象为 null 或未定义,这种情况一般是组件继承后,无法继承到在构造函数里定义的属性或方

ie8-file.[0].size如何兼容ie低版本

问题描述 file.[0].size如何兼容ie低版本 ie低版本下提示"无法获取属性0的值,对象为null或未定义",没有C币,求教大神解答 解决方案 file[0].size多了一个点. 解决方案二: ie8-file对象没有fiels属性,不用搞了

后台接口-后台如何控制移动端的版本数据兼容,低版本不识别高版本的值

问题描述 后台如何控制移动端的版本数据兼容,低版本不识别高版本的值 移动端要更新新的版本但是旧的版本不识别字段传入的新的值,例如:移动端只认识yellow这个值但是后续更新颜色要传入red,旧的版本一读取到red就崩溃,后台做什么处理能进行版本兼容 解决方案 如果你们没有版本标志,你们新版本还是新建立一个接口吧- 老的接口就不要出现其他的值了. 解决方案二: 数据中加个版本标识,你肯定判断当前支持的版本,来处理不同的数据

淘宝不支持低版本浏览器,设置了UserAgent也还是提示,奇怪了。

问题描述 淘宝不支持低版本浏览器,设置了UserAgent也还是提示,奇怪了. HttpWebRequest sendreq1sessionidpost = WebRequest.Create("https://login.taobao.com/member/login.jhtml") as HttpWebRequest; sendreq1sessionidpost.Method = "post"; sendreq1sessionidpost.CookieConta

兼容低版本浏览器的css3 中border-radius和box-shadow(使用文件ie-css3.htc)

推荐一个文件,用来解决css3中border-radius和box-shadow(两个经常用的)   1.border-radius 边框圆角 静态页中经常要求出现某个背景是圆角的,这个时候就要用如下代码,可以很好解决低版本不兼容的问题     (文件ie-css3.htc放在了根目录下)   2.box-shadow 盒子阴影 ,背景添加阴影,使页面更加具有立体感,也是静态页中经常出现的问题,(颜色只支持#000)     上面这两个是这几天经常碰到的,写出来分享

低版本浏览器如何运行ECMAScript6特性

ECMAScript 6介绍 ECMAScript 6 于2015年6月正式成为了标准,关于ES6,我们最大的疑虑可能是客户端浏览器还没有完全支持它,也就node.js用用. 有很多种手段可以解决这个问题,比如:通过webpack(请参考博主webpack系列的文章)与babel-loader.如下图,浏览器借助它们就能跑ES6语法了,也没有增加js负荷(1.6KB).以下的ES6特性,都可以放心的使用. BABEL官网链接     Arrows and Lexical This    Clas

让低版本浏览器支持input的placeholder属性(js方法)_javascript技巧

复制代码 代码如下: var doc = window.document, input = doc.createElement('input'); if( typeof input['placeholder'] == 'undefined' ) // 如果不支持placeholder属性 { $('input').each(function( ele ) { var me = $(this); var ph = me.attr('placeholder'); if( ph && !me.v