我有这个代码:
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. 执行此代码片段,允许客户端将内容作为 .txt 文件从内存中下载 5. 再做一个 res.render()
如果我们排除两个 res.render(),一切正常。完成后,我无法设置标题。我收到此错误。
Error: Can't set headers after they are sent.
所以我想到了一个可能的解决方案。
app.post() 是否有可能获取发布数据并执行 res.render()。
然后,返回发布数据,因此代码的另一部分将处理以该数据作为参数调用函数,然后执行 header 操作,最后执行最后的 res.render()。
请记住这是 routes.js 文件。
最佳答案
HTTP 是一种请求/响应协议(protocol)。客户端发出请求并得到一个且只有一个响应。因此,您永远不能对同一个请求调用 res.render()
两次。
您的问题实际上是由这个所需的序列定义的:
- 客户端发送请求
- 服务器开始处理请求
- 客户展示进度
- 服务器完成处理请求
- 客户展示最终结果
有很多方法可以实现:
客户端使用 Ajax 而不是表单 post 来发送请求
- 客户通过 Ajax 提交表单而不是提交表单
- 客户使用 DOM 操作(更改当前页面内容,通常显示某种类型的视觉叠加层)在页面上显示进度
- 服务器根据请求工作,还没有返回任何东西
- 服务器完成请求并返回响应给客户端一个
res.render()
- 客户端要么将返回的内容插入当前页面,要么发出
window.location = xxxx
以更改当前页面以显示包含新内容的新 URL。
使用 webSocket/socket.io 获取最终结果的表单发布响应
- 客户提交表格
- 服务器立即返回显示进度/等待 UI 的响应页面,并且该页面还将 webSocket 或 socket.io 连接连接到服务器
- 服务器根据要求工作
- 服务器接受 webSocket 或 socket.io 连接
- 服务器完成请求并通过 webSocket/socket.io 连接向正确的客户端发送某种类型的结果
- 客户端通过 webSocket/socket.io 接收响应并更新当前页面的内容或将页面更改为新的 URL
全部通过 webSocket/socket.io 完成
- 客户端加载原始页面
- 客户端与服务器建立 webSocket/socket.io 连接
- 客户端通过 webSocket/socket.io 连接向服务器发送表单数据
- 客户张贴进度/等待覆盖
- 服务器开始处理请求
- 服务器完成处理请求
- 服务器通过客户端的 webSocket/socket.io 连接将来自请求的响应发送回客户端。
- 客户端通过 webSocket/socket.io 连接接收响应并更新当前页面的内容或将页面更改为新的 URL
关于javascript - express 返回帖子信息由另一个功能处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52065832/