Express.js res.render()和res.redirect() [英] Express.js res.render() and res.redirect()
本文介绍了Express.js res.render()和res.redirect()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我的Express应用程序中有一条路线,应该执行以下操作:
I have a route in my express app, which is supposed to do the following:
- 从外部获取一些数据(确定)
- 显示一个带有socket.io的HTML页面,以侦听消息(确定)
- 执行一些计算,这需要很长时间
- 每完成一次,便通过socket.io发送一条消息(确定)
- 所有计算完成后,显示结果页(问题)
- Get some data from outside (OK)
- Show a HTML page with socket.io listening for messages (OK)
- Perform some calculations, which take a long time
- Send a message trough socket.io after each one one completed (OK)
- When all calculations are completed, show a result page (problem)
所以,我的代码的简化版本是:
So, a simplified version of my code is:
module.exports = function(io) { // This is so I can use socket.io inside the route
var express = require('express');
var router = express.Router();
[... and other required]
router.post('/', function(req, res, next) {
res.render('loading'); // This renders the template which holds accepts and renders socket.io messages
pefromCalculaton();
sendSocketIOMessage();
session.data = resultData; // I get the result of all calculations and put that in the session. It's a quick fix, don't judge, I've got no presistancy in my project as for now...
res.redirect('results'); // And here I'd like to go to the other route, which will display the data, getting it from the session.
});
return router;
}
由于这不起作用,我可能正在尝试做一些愚蠢的事情这里。但是我真正想做的是:
Since this doesn't work, I am probably trying to do something really stupid here. But what I actually want to do is:
- 执行计算
- 在执行计算时,更新使用套接字的进度
- 计算完成后,呈现一个模板,显示所有结果。
推荐答案
好,我的朋友,正如您所知,一个请求中不能发送两个响应。因此,这就是您需要做的。
Well, my friend, as you know that one can't send two responses from within one request. So here is what you need to do.
module.exports = function(io) { // This is so I can use socket.io inside the route
var express = require('express');
var router = express.Router();
[... and other required]
router.post('/', function(req, res, next) {
var taskId = (new Date()).getTime(); //timestamp to get unique task id.
res.render('loading');
startCalculations(function(progressIndicator){ //progress callback
io.emit('progress',progressIndicator);
},function(result){ // Finish callback
session[taskId] = result;
io.emit('finish',{ taskid: taskId });
});
});
router.get('/result:taskId', function(req, res, next) {
var result = session[req.params.taskId];
if(!result)
{
//Result already consumed!
res.render('expired');
return;
}
delete session[req.params.taskId];
res.render('result', {result: result});
});
//progress callback will be called when we want to report progress
//done callback indicates our results are ready.
function startCalculations(progress, done){
//This is just a stupid piece of code, just to emulate loading.
//Your awesome async code will replace this
//In your case it will not be a loop and there will be a callback
//To signal finish.
var result = 0;
for(i = 0; i < 100; i++)
{
result = result + i;
//Simulate progress
progress(i);
}
//Simulate finish -- result has 0 to 99 all added up ;)
done(result);
}
return router;
}
现在在html前面您可以拥有...
Now on the html front you can have ...
这是您的
正在加载
视图的样子。
<script src="/socket.io/socket.io.js"></script>
<script src="http://code.jquery.com/jquery-1.11.1.js"></script>
<script>
var socket = io();
//Init code.
socket.on('progress', function(progressIndicator){
//Your jquery mojo to show progress
displayProgress(progressIndicator);
});
socket.on('finish', function(task){
//Redirect to result page from frontend (you were trying to do
//on backend -- node.js)
window.location.href = "/result/" + task.taskId;
//OR
//window.location.replace("/result/" + task.taskId);
});
</script>
希望这是有道理的,对您有帮助...
Hope this makes sense and helps ...
让我知道您是否还需要其他东西。
Let me know if you need anything else.
玩得开心!
这篇关于Express.js res.render()和res.redirect()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文