Express 的 res.end() 是如何工作的?

How does Express's res.end() work?

docs真的不多说了

Ends the response process. Inherited from Node's http.ServerResponse.

Use to quickly end the response without any data. If you need to respond with data, instead use methods such as res.send() and res.json().

res.end();
res.status(404).end();
  1. 所以有没有东西寄给客户?我感觉到发送了状态行和 headers,但没有发送 body。否则他们为什么要举 res.status(404).end().

    的例子
  2. 如果您向 res.end() 提供参数,它会像 Node 的 response.end() 一样发送您在响应 body 中提供的参数吗?

当您发回信息时,您必须结束信息流。您可以通过调用 end() 来完成此操作。发送状态代码 404 后仍然可以跟内容,例如自定义 404 页面,而不是浏览器向您显示默认 This page can not be found (Old, but an example of Chrome's built-in 404 page)。如果不结束请求,浏览器会一直等待流结束,并在一定时间后报超时。

res.send() 自动为您关闭请求,这样您就不必手动调用 end()

如果我们看source, we see that express doesn't actually provide a end() method. That's what the docs’ “Inherited from Node's http.ServerResponse” tells you – express doesn't provide this method; node core's http module does.

那么 http 的 end() 有什么作用?

  1. 如果 HTTP 响应 headers 尚未发送,它们将被写入响应流。
  2. 如果使用 data 参数调用 end(),数据将传递给 write()
  3. 如果有必要发送 trailers,这些将被写入响应流。
  4. 在响应 object 上发出 finish 事件,其中:

    • 如果连接使用 keep-alive,节点开始处理下一个 HTTP 请求。
    • 否则,底层 TCP 套接字将关闭。

所以回答你的问题:

  1. 有没有寄东西给客户?这取决于。调用 end() 永远不会导致发送额外的有效负载 (entity-body) 数据,但取决于您在调用 end() 之前对响应所做的操作,更多字节 可能 由节点代表您写入底层套接字。

    你的直觉是正确的; res.status(404).end() 将导致服务器响应 HTTP 404 headers 和 Content-Length 为零(完全为空 body)。

  2. 是的,传递给end()的数据被写入响应流,因为end()方法节点的。重要的是要记住,express 给你的请求和响应 object 只是 extra 方法形式的 express 的常规 http.IncomingMessage and http.ServerResponse objects that are augmented with some additional functionality。 node core 提供的所有方法仍然可用。

我刚刚意识到在不传递任何数据的情况下以 res.end( ) 结束流并没有按预期结束流。这种情况发生在渲染文件并随文件发送数据的情况下,您必须显式调用 res.end( JSON.stringify( {data: data} ) )。不知道还有没有人遇到过类似的情况。没有在文档中找到它,我花了一些时间才弄明白为什么渲染花了这么长时间却没有成功。