如何从JavaScript中拒绝WebSocket打开握手读取状态代码?

Art*_*tas 15 javascript websocket

我用JavaScript创建了一个WebSocket客户端

if ("WebSocket" in window) {            
    ws = new WebSocket(url);
    ws.binaryType = "arraybuffer";      
} else if ("MozWebSocket" in window) {  
    ws = new MozWebSocket(url);
    ws.binaryType = "arraybuffer";  
}
Run Code Online (Sandbox Code Playgroud)

和WebSocket服务器应用程序.在某些情况下,我将服务器编程为拒绝连接请求并提供错误代码.

在例如Firefox控制台中,然后会显示一条消息

Firefox can't establish a connection to the server at ws://123.123.123.123:1234/.
Run Code Online (Sandbox Code Playgroud)

它提供了状态代码

HTTP/1.1 403 
Run Code Online (Sandbox Code Playgroud)

这是我的WebSocket服务器发送的错误代码.

我的问题是:如何在JavaScript客户端中读取此状态代码?

ws.onerror = function(e) {
    console.log(e);     
};   
ws.onclose = function(e) {
    console.log(e); 
};
Run Code Online (Sandbox Code Playgroud)

都被调用,但没有任何Event对象包含此错误代码.

Mic*_*pat 14

规范禁止从WebSocket对象读取HTTP状态代码(或类似的东西),因为否则WebSocket对象可用于探测非WebSocket端点,这将是一个安全问题:

用户代理不得以允许脚本区分以下情况的方式向脚本传达任何故障信息:

  • 无法解析主机名的服务器.
  • 无法成功路由数据包的服务器.
  • 拒绝指定端口上的连接的服务器.
  • 无法正确执行TLS握手的服务器(例如,无法验证服务器证书).
  • 未完成打开握手的服务器(例如,因为它不是WebSocket服务器).
  • WebSocket服务器发送了正确的打开握手,但指定了导致客户端断开连接的选项(例如,服务器指定了客户端未提供的子协议).
  • 成功完成打开握手后突然关闭连接的WebSocket服务器.

- https://www.w3.org/TR/websockets/#feedback-from-the-protocol


还有另一种方法可以做到这一点!

WebSocket协议允许自定义关闭代码:

4000-4999

4000-4999范围内的状态代码保留供私人使用,因此无法注册.这些代码可以由WebSocket应用程序之间的先前协议使用.该协议未对这些代码的解释进行定义.

- https://tools.ietf.org/html/rfc6455#section-7.4.2

在您的服务器端逻辑中,即使您最终想要拒绝连接(比如说用户当前未经身份验证),请执行以下操作:

  1. 接受WebSocket连接
  2. 立即关闭具有自定义关闭状态的连接

客户端现在可以查看CloseEvent.code以了解连接被拒绝的原因.

每次服务器要拒绝WebSocket连接时,您都不需要这样做.例如,如果请求不是正确的WebSocket请求,或者出于安全原因(如果反CSWSH Origin检查失败),我仍然会拒绝4xx HTTP状态的连接.对于希望客户端逻辑处理的情况,您只需要使用WebSocket关闭状态.