我的套接字当前抛出 net::ERR_CONNECTION_REFUSED,因为服务器没有运行,我希望它现在这样做。
问题是下面的代码没有捕捉到错误。在控制台中,我在第 2 行看到一个异常(带有 net::ERR_CONNECTION_REFUSED),我认为它不应该发生,因为它在 try 语句中。
1 try {
2 ws = new WebSocket('ws://'+ host + ':' + port + '/');
3 }
4 catch (err) {
5 console.log('This never prints');
6 }
7 ws.onerror = function (error) {
8 console.log(error);
9 };
所以我的问题是为什么它没有被捕获?
我最终想要的是在其他地方显示错误消息,但我无法捕捉到它,第 8 行打印了一个没有提及 net::ERR_CONNECTION_REFUSED 的“事件”对象,所以我不确定如何获取错误消息。
最佳答案
WebSocket
的连接时间错误导致调度事件,而不是抛出值。这是因为 throw
操作必须是同步的。为了将所有连接时错误作为抛出错误来处理,WebSocket
构造函数需要完全暂停所有脚本执行和 UI 交互,直到整个 WebSocket 握手完成。相反,连接过程异步运行,从而允许浏览器线程在 WebSocket 连接在后台初始化时继续工作。由于连接的异步性质,WebSocket
必须通过 error
事件报告错误,因为同步 new WebSocket
操作在异步连接任务遇到错误。
您看到的ERR_CONNECTION_REFUSED
消息纯粹是为了开发人员的利益;脚本无法以任何方式访问它。它在 JavaScript 环境中没有任何表示。它只是出现在您的控制台中的一条红色消息,用于通知您,也就是正在查看浏览器的人,有一个错误。
error
处理程序事件是响应失败的正确位置,但缺少脚本可读的连接时错误信息是设计使然。来自WHATWG spec for the WebSocket API :
User agents must not convey any failure information to scripts in a way that would allow a script to distinguish the following situations:
- A server whose host name could not be resolved.
- A server to which packets could not successfully be routed.
- A server that refused the connection on the specified port.
- A server that failed to correctly perform a TLS handshake (e.g., the server certificate can't be verified).
- A server that did not complete the opening handshake (e.g. because it was not a WebSocket server).
- A WebSocket server that sent a correct opening handshake, but that specified options that caused the client to drop the connection (e.g. the server specified a subprotocol that the client did not offer).
- A WebSocket server that abruptly closed the connection after successfully completing the opening handshake.
[...] Allowing a script to distinguish these cases would allow a script to probe the user's local network in preparation for an attack.
浏览器故意省略了规范要求的任何有用信息。规范作者担心访问此信息可能会允许恶意网页获取有关您的网络的信息,因此他们要求浏览器以无法区分的方式报告所有连接时间错误。
关于Javascript 无法捕获 WebSocket 实例化中的错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31002592/