如何使用 JavaScript 从拒绝的 WebSocket 打开握手中读取状态代码? [英] How to read status code from rejected WebSocket opening handshake with JavaScript?

查看:29
本文介绍了如何使用 JavaScript 从拒绝的 WebSocket 打开握手中读取状态代码?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I created a WebSocket client in JavaScript

if ("WebSocket" in window) {            
    ws = new WebSocket(url);
    ws.binaryType = "arraybuffer";      
} else if ("MozWebSocket" in window) {  
    ws = new MozWebSocket(url);
    ws.binaryType = "arraybuffer";  
}

和一个 WebSocket 服务器应用程序.在某些情况下,我对服务器进行了编程以拒绝连接请求并提供错误代码.

and a WebSocket server application. For certain cases I programmed the server to reject the connection request and provide an error code.

例如Firefox 控制台然后显示一条消息

In e.g. Firefox Console then a message is shown

Firefox can't establish a connection to the server at ws://123.123.123.123:1234/.

并提供状态码

HTTP/1.1 403 

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

which is the error code that I have sent by my WebSocket server.

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

My question is: how can I read this status code in my JavaScript client?

ws.onerror = function(e) {
    console.log(e);     
};   
ws.onclose = function(e) {
    console.log(e); 
};

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

are both called, but none of the Event objects contains this error code.

推荐答案

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

The spec forbids reading the HTTP status code (or anything like it) from the WebSocket object because otherwise the WebSocket object could be used to probe non-WebSocket endpoints, which would be a security issue:

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

User agents must not convey any failure information to scripts in a way that would allow a script to distinguish the following situations:

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

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

不过还有另一种方法!

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

The WebSocket protocol allows for custom close codes:

4000-4999

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

Status codes in the range 4000-4999 are reserved for private use and thus can't be registered. Such codes can be used by prior agreements between WebSocket applications. The interpretation of these codes is undefined by this protocol.

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

在您的服务器端逻辑中,即使您最终想要拒绝连接(比如用户当前未经身份验证),也请改为这样做:

In your server-side logic, even when you ultimately want to reject the connection (like say the user is currently unauthenticated), do this instead:

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

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

The client can now look at the CloseEvent.code to know why the connection was rejected.

您不需要每次服务器想要拒绝 WebSocket 连接时都这样做.例如,如果请求不是正确的 WebSocket 请求,或者出于安全原因(例如 anti-CSSWH 来源检查失败).对于希望客户端逻辑处理的情况,您只需使用 WebSocket 关闭状态.

You don't need to do this every time the server wants to reject a WebSocket connection. For example, I'd still reject the connection with a 4xx HTTP status if the request isn't a proper WebSocket request, or for security reasons (like if the anti-CSWSH Origin check fails). You only need to use the WebSocket close status for cases that you want the client-side logic to handle.

这篇关于如何使用 JavaScript 从拒绝的 WebSocket 打开握手中读取状态代码?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆