【问题标题】:Why can't we do multiple response.send in Express.js?为什么我们不能在 Express.js 中做多个 response.send?
【发布时间】:2014-08-28 06:54:09
【问题描述】:

3 年前,我可以在 express.js 中执行多个 res.send
甚至写一个setTimeout 来显示实时输出。

response.send('<script class="jsbin" src="http://code.jquery.com/jquery-1.7.1.min.js"></script>');
response.send('<html><body><input id="text_box" /><button>submit</button></body></html>');
var initJs = function() {
  $('.button').click(function() {
    $.post('/input', { input: $('#text_box').val() }, function() { alert('has send');});
  });
}
response.send('<script>' + initJs + '</script>');

现在它会抛出:

Error: Can't set headers after they are sent

我知道 nodejs 和 express 已经更新。为什么现在不能这样做?还有什么想法吗?


找到了解决方案,但 res.write 不在 api 参考中 http://expressjs.com/4x/api.html

【问题讨论】:

  • API参考页上有一行写着“res对象是Node自带的response对象的增强版,支持所有内置的字段和方法”,response.write是内置的方法。

标签: node.js express


【解决方案1】:

也许你需要:response.write

response.write("foo");
response.write("bar");
//...
response.end()

res.send 隐式调用res.write,后跟res.end。如果您多次致电res.send,它将在第一次工作。但是,由于第一个 res.send 调用结束了响应,因此您无法向响应中添加任何内容。

【讨论】:

  • 是的,听起来他大概就是这么想的。我完全忘记了 Node 的response.write;我的大脑在 Express 领域:/
  • 酷,这就是我想要的。但是,为什么它不在 api 参考中 expressjs.com/4x/api.html#res.send ???
  • 也许是因为我们应该使用res.renderres.send,所以我在新手时使用res.write。 @emj365 为什么不试试res.render
  • respone.writeresponse.writeHead 来自 http.ServerResponse api node doc
【解决方案2】:

response.send 向客户端发送完整的 HTTP 响应,包括标头和内容,这就是您无法多次调用它的原因。事实上,它甚至结束了响应,所以在使用response.send时不需要显式调用response.end

在我看来,您正在尝试将send 用作缓冲区:写入它是为了稍后刷新。然而,这不是该方法的工作原理;您需要在代码中建立响应,然后进行一次 send 调用。

不幸的是,我无法说明为什么或何时进行此更改,但我知道至少从 Express 3 开始就是这样。

【讨论】:

    【解决方案3】:

    res.write 立即向客户端发送字节

    我只是想更清楚地说明res.write 的这一点。

    它不会建立回复并等待res.end()。它只是立即发送。

    这意味着当您第一次调用它时,它将发送包含状态的 HTTP 回复标头,以便获得有意义的响应。因此,如果您想设置状态或自定义标头,则必须在第一次调用之前完成,就像 send() 一样。

    请注意,write() 不是您通常想要在简单的 Web 应用程序中执行的操作。浏览器一点一点地得到回复增加了事情的复杂性,所以你只会在真正需要的时候才去做。

    使用res.locals 跨中间件构建回复

    这是我最初的用例,res.locals 非常适合。我可以在那里将数据存储在一个数组中,然后在最后一个中间件上将它们连接起来并执行最终的send 以立即发送所有内容,例如:

      async (err, req, res, next) => {
        res.locals.msg = ['Custom handler']
        next(err)
      },
      async (err, req, res, next) => {
        res.locals.msg.push('Custom handler 2')
        res.status(500).send(res.locals.msg.join('\n'))
      }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-24
      • 2012-04-22
      • 1970-01-01
      • 2018-10-24
      • 2020-08-05
      • 1970-01-01
      相关资源
      最近更新 更多