res.end()和res.send()有什么区别?

274

我是一个初学者,正在学习Express.js,我对这两个关键词感到困惑:res.end()res.send()

它们是相同的还是不同的?


4
我认为在纯 Node.js 中使用 res.end,而在 Express 框架中使用 res.send - Muhammad Umer
2
response.send 包含一个 response.end 调用。 - Константин Ван
6个回答

285
首先,res.send()res.end()不同的
我想更加强调一下res.end()res.send()之间在响应头方面的一些关键区别以及它们的重要性。 1. res.send()会根据输出的结构来设置相应的头信息。
    app.get('/',(req,res)=>{
       res.send('<b>hello</b>');
    });

enter image description here


     app.get('/',(req,res)=>{
         res.send({msg:'hello'});
     });

enter image description here

使用res.end()只能回复文本,并且不会设置"Content-Type"。
      app.get('/',(req,res)=>{
           res.end('<b>hello</b>');
      }); 

enter image description here

2. res.send()会在响应头中设置"ETag"属性。
      app.get('/',(req,res)=>{
            res.send('<b>hello</b>');
      });

enter image description here

为什么这个标签很重要?
ETag HTTP响应头是一个特定版本资源的标识符。它使缓存更高效,并节省带宽,因为如果内容没有改变,Web服务器不需要发送完整的响应。 res.end() 不会设置这个头属性。

24
我认为这应该被接受作为答案......重点放在可能破坏你工作日的实际差异上,而不是讨论带/不带内容的结束响应。 - Tomas
4
基本上将.end()视为低级函数,并在Express应用程序中使用.send() - Eric Burel
保持简单和愚蠢 :) +1 - VishalParkash
@EricBurel 是的。.send 在内部调用了 .end - Константин Ван
这部分回答是错误的:使用res.end()只能响应文本res.send()内部使用res.setHeader("content-type", myContentType)来设置内容类型,然后使用res.end(data...)发送数据。res.end()可以发送各种类型的数据,不仅仅是文本。 - Welcor

204

首先,res.send()res.end()不同的

res.send() 会发送HTTP响应。它的语法是,

res.send([body])

body参数可以是一个Buffer对象、一个字符串、一个对象或一个数组。例如:

res.send(new Buffer('whoop'));
res.send({ some: 'json' });
res.send('<p>some html</p>');
res.status(404).send('Sorry, we cannot find that!');
res.status(500).send({ error: 'something blew up' });

查看此链接以了解更多信息。

res.end()会结束响应过程。这个方法实际上来自于Node核心,具体地说是http.ServerResponseresponse.end()方法。它用于在没有任何数据的情况下快速结束响应。例如:

res.end();
res.status(404).end();

阅读此文以获得更多信息。


99
但是,res.end实际上可以像res.send一样工作,因为您可以通过传递字符串参数来将其添加为响应主体。除此之外,res.send还结束了响应。那么它们在功能上有什么不同呢? - saltthehash
45
如果您将字符串传递给res.send(),它会自动假定Content-Type为html。 然而,res.end()只是在响应流上调用了Node的底层end()实现,因此不会对Content-Type进行任何假设。 - abagh0703
3
我必须点赞这个帖子,纯粹因为我从未使用过 express,但从标题认为 - 一个发送东西,另一个结束东西....没错。 - Darren Bartrup-Cook
3
如果只使用 res.send() 而不传入任何内容,那么会像使用 res.end() 一样吗? - CMCDragonkai
3
请看下面的答案背后发生了什么,了解它们之间的区别。 - KunYu Tsai
显示剩余2条评论

62

res.send() 实现了 res.write, res.setHeadersres.end 的功能:

  1. 它会检查您发送的数据并设置正确的响应头。
  2. 然后使用 res.write 流式传输数据。
  3. 最后,使用 res.end 来结束请求。

在某些情况下,您可能需要手动执行此操作,例如,如果要流式传输文件或大型数据集,则需要自己设置标头并使用 res.write 保持流传输。


9

除了出色的答案外,我想在这里强调一下,何时使用res.end()和何时使用res.send(),这就是我最初来到这里并且没有找到解决方案的原因。

答案非常简单。

res.end()用于快速结束响应而不发送任何数据。

一个示例是在服务器上启动一个进程:

app.get('/start-service', (req, res) => {
   // Some logic here
   exec('./application'); // dummy code
   res.end();
});

如果您想在响应中发送数据,则应使用res.send()代替。
app.get('/start-service', (req, res) => {
   res.send('{"age":22}');
});

在这里你可以阅读更多内容:

7

res.send() 用于向客户端发送响应,而res.end()用于结束您发送的响应。

res.send()自动调用res.end(),因此在res.send()之后不需要调用或提及它。


5

res是一个HttpResponse对象,它继承自OutgoingMessage。res.send调用res.end并由OutgoingMessage实现来发送HTTP响应和关闭连接。我们在这里看到代码。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接