Javascript 不会在 WebSocket 实例化中捕获错误
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/31002592/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Javascript doesn't catch error in WebSocket instantiation
提问by andyhasit
My socket currently throws net::ERR_CONNECTION_REFUSED because the server isn't running, which I want it to do at the moment.
我的套接字当前抛出 net::ERR_CONNECTION_REFUSED 因为服务器没有运行,我现在希望它这样做。
The problem is that the following piece of code doesn't catch the error. In the console I see an exception on line 2 (with net::ERR_CONNECTION_REFUSED) which I believe shouldn't happen as it's within a try statement.
问题是以下代码没有捕获错误。在控制台中,我在第 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 };
So my question is why is it not being caught?
所以我的问题是为什么它没有被抓住?
What I ultimately want is the error message to be displayed elsewhere, but I can't catch it, and line 8 prints an "event" object which doesn't mention net::ERR_CONNECTION_REFUSED, so I'm not sure how to get the error message out.
我最终想要的是在别处显示的错误消息,但我无法捕捉到它,第 8 行打印了一个没有提及 net::ERR_CONNECTION_REFUSED 的“事件”对象,所以我不知道如何获得错误信息出来。
回答by apsillers
The WebSocket
's connection-time error causes a dispatched event, not a thrown value. This is because throw
operations must be synchronous. In order to handle all connection-time errors as thrown errors, the WebSocket
constructor would need to completely suspend all script execution and UI interaction until the entire WebSocket handshake had completed. Instead, the connection process runs asynchronously, thereby allowing the browser thread to continue working while the WebSocket connection initializes in the background. Because of the connection's asynchronous nature, the WebSocket
must report errors via error
events, since the synchronous new WebSocket
operation has already finished by the time the asynchronous connection task encounters an error.
在WebSocket
记者连线时发生错误导致调度的事件,而不是抛出值。这是因为throw
操作必须是同步的。为了将所有连接时错误作为抛出的错误处理,WebSocket
构造函数需要完全挂起所有脚本执行和 UI 交互,直到整个 WebSocket 握手完成。相反,连接进程异步运行,从而允许浏览器线程在 WebSocket 连接在后台初始化时继续工作。由于连接的异步性质,WebSocket
必须通过error
事件报告错误,因为new WebSocket
在异步连接任务遇到错误时同步操作已经完成。
The ERR_CONNECTION_REFUSED
message you see is purely for the benefit of developers; it is not accessible to the script in any way. It does not have any representation within the JavaScript environment. It's just a red-colored message that appears in your console to inform you, the human looking at the browser, about an error.
ERR_CONNECTION_REFUSED
您看到的消息纯粹是为了开发人员的利益;脚本无法以任何方式访问它。它在 JavaScript 环境中没有任何表示。它只是出现在您的控制台中的一条红色消息,通知您(正在查看浏览器的人)出现错误。
The error
handler event is the correct place to respond to failure, but the lack of script-readable connection-time error information is by design. From the WHATWG spec for the WebSocket API:
在error
处理事件的正确位置对失败,但缺乏剧本可读连接时错误信息是由设计。来自WebSocket API的WHATWG 规范:
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.
用户代理不得以允许脚本区分以下情况的方式向脚本传达任何失败信息:
- 无法解析主机名的服务器。
- 数据包无法成功路由到的服务器。
- 拒绝指定端口上的连接的服务器。
- 未能正确执行 TLS 握手的服务器(例如,无法验证服务器证书)。
- 未完成打开握手的服务器(例如,因为它不是 WebSocket 服务器)。
- 发送正确打开握手的 WebSocket 服务器,但指定了导致客户端断开连接的选项(例如,服务器指定了客户端未提供的子协议)。
- 成功完成打开握手后突然关闭连接的 WebSocket 服务器。
[...] 允许脚本区分这些情况将允许脚本探测用户的本地网络以准备攻击。
The browser is deliberately omitting any useful information as required by the spec. The spec authors are concerned that access to this information could allow a malicious Web page to gain information about your network, so they require browsers report all connection-time errors in an indistinguishable way.
浏览器故意省略规范要求的任何有用信息。规范作者担心访问此信息可能允许恶意网页获取有关您的网络的信息,因此他们要求浏览器以无法区分的方式报告所有连接时间错误。
回答by Kunal Pradhan
I tried creating fiddle with it and I am able to see line printed.
我试着用它来创造小提琴,我能够看到打印的线条。
host='localhost';
port=100;
try {
ws = new WebSocket('ws://'+ host + ':' + port + '/');
}
catch (err) {
console.log('This never prints');
}
ws.onerror = function (error) {
console.log(error);
};