检查WebSocket是否为hixie客户端



根据维基百科,大多数浏览器使用RFC6455或稍早的版本,握手几乎相同。我使用的服务器仅支持RFC6455或类似版本,根据指定的版本,它接受Origin:Sec-WebSocket-Origin:

Safari 5和iOS 5使用的是WebSocket的hixie版本。如果WebSocket丢失,我通常会返回到长轮询。Safari5有一个WebSocket对象,但握手有很大不同。

有没有什么方法可以检测WebSocket是hixie,还是属于Safari 5,这样我就可以忽略它而不尝试握手?有没有任何方法可以在不依赖用户代理的情况下检查浏览器是否为Safari 5?

根据2009年WebSocket W3C草案,CLOSED常数的值为2:

[Constructor(in DOMString url, in optional DOMString protocol)]
interface WebSocket {
  ...
  // ready state
  const unsigned short CONNECTING = 0;
  const unsigned short OPEN = 1;
  const unsigned short CLOSED = 2;
  ...
};
WebSocket implements EventTarget;

在2011年W3C草案中,CLOSED的值为3:

[Constructor(in DOMString url, in optional DOMString protocols)]
[Constructor(in DOMString url, in optional DOMString[] protocols)]
interface WebSocket {
  ...
  // ready state
  const unsigned short CONNECTING = 0;
  const unsigned short OPEN = 1;
  const unsigned short CLOSING = 2;
  const unsigned short CLOSED = 3;
  ...
};

如维基百科图表所示,2009年的草案对应于hixie/hibi-00,而2011年的草案则对应于hibi-07及更高版本。

有了这些信息,您可以进行如下JavaScript检查:

if("WebSocket" in window && WebSocket.CLOSED > 2) {
    // hibi-07 to RFC6455
} else {
    // No WebSocket, or hixie
}

我在浏览器屏幕截图服务上使用了以下测试页面:

<html>
<body>
<div id="test"></div>
<script>
var test = document.getElementById("test");
var text = "no soup for you!";
if ("WebSocket" in window) {
    text = "WebSocket " + WebSocket.CLOSED;
} else if("MozWebSocket" in window) {
    text = "MozWebSocket " + MozWebSocket.CLOSED;
}
test.appendChild(document.createTextNode(text));
</script>
</body>
</html>

Safari 5和Chrome 12及以下版本返回2,而Safari 6和Chrome 14及以上版本返回3用于CLOSED

Chrome 13使用hixie,但返回3。这是我能找到的唯一边缘案例。由于Chrome自动更新,Chrome 13的用户应该为零。

注意:这些常量在WebSocket构造函数和WebSocket.protype上都有设置。Safari 5.0 5.1之前的版本仅在WebSocket_protype上设置这些常量。如果您只计划支持RFC6455及更高版本,则WebSocket.CLOSED > 2WebSocket.CLOSED === 3就足够了。

相关内容

  • 没有找到相关文章

最新更新