事件:'clientError'


【Event: 'clientError'

如果客户端连接触发 'error' 事件,它将被转发到这里。该事件的监听器负责关闭或销毁底层套接字。例如,可以希望通过自定义的 HTTP 响应更优雅地关闭套接字,而不是突然断开连接。套接字必须在监听器结束之前关闭或销毁

【If a client connection emits an 'error' event, it will be forwarded here. Listener of this event is responsible for closing/destroying the underlying socket. For example, one may wish to more gracefully close the socket with a custom HTTP response instead of abruptly severing the connection. The socket must be closed or destroyed before the listener ends.】

此事件保证会传递一个 <net.Socket> 类的实例,该类是 <stream.Duplex> 的子类,除非用户指定了其他类型的套接字而不是 <net.Socket>

【This event is guaranteed to be passed an instance of the <net.Socket> class, a subclass of <stream.Duplex>, unless the user specifies a socket type other than <net.Socket>.】

默认行为是尝试使用 HTTP '400 Bad Request' 关闭套接字,或者在发生 HPE_HEADER_OVERFLOW 错误的情况下使用 HTTP '431 Request Header Fields Too Large'。如果套接字不可写或当前附加的 http.ServerResponse 的头信息已发送,它会被立即销毁。

【Default behavior is to try close the socket with a HTTP '400 Bad Request', or a HTTP '431 Request Header Fields Too Large' in the case of a HPE_HEADER_OVERFLOW error. If the socket is not writable or headers of the current attached http.ServerResponse has been sent, it is immediately destroyed.】

socket 是错误来源的 net.Socket 对象。

import http from 'node:http';

const server = http.createServer((req, res) => {
  res.end();
});
server.on('clientError', (err, socket) => {
  socket.end('HTTP/1.1 400 Bad Request\r\n\r\n');
});
server.listen(8000);const http = require('node:http');

const server = http.createServer((req, res) => {
  res.end();
});
server.on('clientError', (err, socket) => {
  socket.end('HTTP/1.1 400 Bad Request\r\n\r\n');
});
server.listen(8000);

'clientError' 事件发生时,不会有 requestresponse 对象,因此任何发送的 HTTP 响应,包括响应头和负载,必须直接写入 socket 对象。必须注意确保响应是格式正确的 HTTP 响应消息。

【When the 'clientError' event occurs, there is no request or response object, so any HTTP response sent, including response headers and payload, must be written directly to the socket object. Care must be taken to ensure the response is a properly formatted HTTP response message.】

err 是一个 Error 实例,并带有两个额外的列:

  • bytesParsed:Node.js 可能已正确解析的请求数据包的字节数;
  • rawPacket:当前请求的原始数据包。

在某些情况下,客户端已经收到了响应和/或套接字已经被销毁,例如发生 ECONNRESET 错误时。在尝试向套接字发送数据之前,最好先检查它是否仍然可写。

【In some cases, the client has already received the response and/or the socket has already been destroyed, like in case of ECONNRESET errors. Before trying to send data to the socket, it is better to check that it is still writable.】

server.on('clientError', (err, socket) => {
  if (err.code === 'ECONNRESET' || !socket.writable) {
    return;
  }

  socket.end('HTTP/1.1 400 Bad Request\r\n\r\n');
});