【问题标题】:Express return post info to be processed by another function快递返回帖子信息由另一个函数处理
【发布时间】:2019-02-03 13:22:31
【问题描述】:

我有这个代码:

 app.post('/pst', function(req, res) {
            var data = req.body.convo;

            res.render('waiting.ejs');  //ADDED THIS

            myFunc(data).then(result => {


            res.render('success.ejs');  //THEN THIS

            //---------------------------------
            //clever way to send text file to client from the memory of the server
            var fileContents = Buffer.from(result, 'ascii');
            var readStream = new stream.PassThrough();
            readStream.end(fileContents);
            res.set('Content-disposition', 'attachment; filename=' + fileName);
            res.set('Content-Type', 'text/plain');
            readStream.pipe(res);
            //--------------------------------------

            }).catch( .....

我想做的是当有 POST 时, 1.抓取帖子信息 2. 做一个 res.render() 3. 以帖子信息为参数运行一个函数 4. 执行此代码 sn-p 将允许客户端从内存中下载内容为 .txt 文件 5. 再做一个 res.render()

如果我们排除两个 res.render(),一切正常。在我做一个之后,我无法设置标题。我收到此错误。

Error: Can't set headers after they are sent.

所以我想到了一个潜在的解决方案。

是否有可能 app.post() 会获取 post 数据并执行 res.render()。

然后,返回post数据,所以另一部分代码将处理以该数据作为参数调用函数,然后进行头部操作,最后进行最后的res.render()。

请记住,这是 routes.js 文件。

【问题讨论】:

  • res 函数应该始终是您调用的最后一个函数。你不能有多个res.render()s。
  • 这就是为什么我问我是否只在这里做一个 res.render,但我将发布数据发送到其他地方进行处理,在那里我可以做另一个。
  • 您在该代码的哪一部分发送要处理的数据?
  • myFunc(data).then(result .data 是来自 POST 的数据,myFunc 是一个异步函数。
  • 是的,但你仍然渲染到相同的res

标签: javascript node.js express routes header


【解决方案1】:

HTTP 是一种请求/响应协议。客户端发出请求并得到一个且只有一个响应。所以,你永远不能在同一个请求上两次调用res.render()

您的问题实际上是由这个期望的顺序定义的:

  1. 客户端发送请求
  2. 服务器开始处理请求
  3. 客户端显示进度
  4. 服务器完成处理请求
  5. 客户端显示最终结果

有很多方法可以做到这一点:

客户端使用 Ajax 代替 form post 来发送请求

  1. 客户端通过 Ajax 提交表单而不是表单发布
  2. 客户端使用 DOM 操作(更改当前页面内容,通常显示某种类型的视觉覆盖)在页面上放置进度
  3. 服务器按请求工作,尚未返回任何内容
  4. 服务器完成请求并向客户端返回一个res.render()的响应
  5. 客户端要么将返回的内容插入当前页面,要么发出window.location = xxxx 来更改当前页面以显示包含新内容的新 URL。

使用 webSocket/socket.io 获得最终结果的表单发布响应

  1. 客户提交表单
  2. 服务器立即返回显示进度/等待 UI 的响应页面,该页面还将 webSocket 或 socket.io 连接连接到服务器
  3. 服务器按要求工作
  4. 服务器接受 webSocket 或 socket.io 连接
  5. 服务器完成请求并通过 webSocket/socket.io 连接将某种类型的结果发送到正确的客户端
  6. 客户端通过 webSocket/socket.io 接收响应并更新当前页面的内容或将页面更改为新的 URL

全部通过 webSocket/socket.io 完成

  1. 客户端加载原始页面
  2. 客户端与服务器建立 webSocket/socket.io 连接
  3. 客户端通过 webSocket/socket.io 连接向服务器发送表单数据
  4. 客户端提出进度/等待覆盖
  5. 服务器开始处理请求
  6. 服务器完成处理请求
  7. 服务器通过该客户端的 webSocket/socket.io 连接将请求的响应发送回客户端。
  8. 客户端通过 webSocket/socket.io 连接接收响应,并更新当前页面的内容或将页面更改为新 URL

【讨论】:

  • 就在我以为我的应用程序已经完成的时候......现在我必须学习 socket.io 哈哈。感谢您的回答。
  • @user1584421 - 第一个选项不需要socket.io。如果您没有其他理由使用 socket.io,我认为第一个选项可以正常工作,除非您的服务器需要很长时间来处理请求以致浏览器超时。
  • 我不知道阿贾克斯。我准时紧张。您是否知道将涵盖这一点的教程,或者甚至可能是关于 SO 的问题,或者可能是第一个选项的工作代码?
  • @user1584421 - 您是否在使用像 jQuery 这样的内置简单 Ajax 支持的客户端框架?对于现代浏览器,这些浏览器中内置的fetch() interface 非常易于使用。
  • 没有它的所有节点和快递。客户端是最小的。我应该阅读有关 fetch() 的信息吗?
猜你喜欢
  • 1970-01-01
  • 2012-03-03
  • 1970-01-01
  • 2020-10-31
  • 1970-01-01
  • 1970-01-01
  • 2016-10-10
  • 1970-01-01
  • 2021-08-14
相关资源
最近更新 更多