javascript Expressjs / Node.js - res.redirect() 未加载页面
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15321933/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Expressjs / Node.js - res.redirect() not loading page
提问by germainelol
I have a page with a route GET /team
which is loading a list of teams, and DEL /team
which is deleting a team from /team/:key
. So you navigate to a team's profile page and delete them from there, on deletion it should redirect you to the /team
page. I have put logs into the console and it is successfully deleting the team
and wierdly, it says it is loading /team
but the browser does not load this. I have put my code below, any ideas?
我有一个页面,GET /team
其中包含一个正在加载团队列表的路线,并且DEL /team
正在从/team/:key
. 因此,您导航到团队的个人资料页面并从那里删除它们,删除时它应该将您重定向到该/team
页面。我已将日志放入控制台,它成功地删除了team
并且奇怪的是,它说它正在加载/team
但浏览器没有加载它。我已经把我的代码放在下面,有什么想法吗?
Routes:
路线:
app.get('/team'/*, lim("Must be logged in to see teams")*/, getAllTeams, function(req, res){
util.log('Serving request for url [GET] ' + req.route.path);
// Pass it the list of all Teams
res.render('team', {'teamsList' : req.teamsList} );
});
app.get('/team/:key', function(req, res) {
util.log('Serving request for url [GET] ' + req.route.path);
Team.findByKey(req.params.key, function(err, teamData){
if(!err && teamData){
teamData = teamData;
res.render('teamDetails', { 'teamData' : teamData } );
} else {
util.log('Error in fetching Team by key : ' + req.params.key);
res.json({
'retStatus' : 'failure',
'msg' : 'Error in fetching Team by key ' + req.params.key
});
}
});
});
/**
* DEL /team/:key
* Delete Team by key
*/
app.del('/team/:key', getAllTeams, function(req, res) {
util.log('Serving request for url [DEL] ' + req.route.path);
Team.remove({key : req.params.key}, function(err){
var message = '';
var retStatus = '';
if (!err) {
util.log('Successfully deleting Team with key: ' + req.params.key);
message = 'Successfully deleting Team with key: ' + req.params.key;
retStatus = 'Success';
res.redirect('/team');
} else {
util.log('Error deleting Team with key: ' + req.params.key + 'Error: ' + util.inspect(err));
res.json({
'retStatus' : 'failure',
'msg' : 'Error in fetching Team with key ' + req.params.key
});
}
});
});
JavaScript + HTML template:
JavaScript + HTML 模板:
button#teamDelete.btn.btn-danger.btn-mini(type="submit", value="Delete Team") Delete
script(type='text/javascript')
$('#teamDelete').live('click',function(){
var teamId = #{teamData.key};
$.post('/team/' + teamId, { _method : 'delete' }, function(response) {
console.log(response);
if(response.retStatus === 'Success') {
if('/team' && '/team' !== "") {
window.location = '/team';
}
}
});
});
console logs:
控制台日志:
10 Mar 11:52:01 - Serving request for url [GET] /team
10 Mar 11:52:02 - Serving request for url [GET] /team/:key
10 Mar 11:52:03 - Serving request for url [DEL] /team/:key
10 Mar 11:52:03 - Successfully deleting Team with key: 1362855941128
10 Mar 11:52:03 - Serving request for url [GET] /team
getAllTeams:
获取所有团队:
var getAllTeams = function(req, res, next){
Team.getAll(function(err, teamsList){
if(!err && teamsList){
req.teamsList = teamsList;
return next();
}
});
};
Team.getAll (Team schema)
Team.getAll(团队架构)
Team.statics.getAll = function(cb){
var query = this.find({});
query.sort({key : -1});
return query.exec(cb);
};
采纳答案by esp
Your request is POST ($.post) and you route is app.del, so it never gets to res.redirect inside app.del route.
您的请求是 POST ($.post),您的路由是 app.del,因此它永远不会到达 app.del 路由内的 res.redirect。
Why don't you use app.post?
你为什么不使用 app.post?
Updated:
更新:
Assuming $.post sends HTTP DEL request here what is happening: server sends 302 response with no data but browser never sends another request to GET route as server instructs it (or does jQuery handle redirects too? Not sure). res.redirect() is actual HTTP response not some internal server-side instruction to re-route the request to another route like you can do in ASP.NET (and which is wrong actually)... Route is designed to receive request, reply with the response and forget about it. You need to separate routes from actual functions processing them, then you will be able to call that function instead of sending redirect.
假设 $.post 在这里发送 HTTP DEL 请求会发生什么:服务器发送没有数据的 302 响应,但浏览器永远不会在服务器指示时向 GET 路由发送另一个请求(或者 jQuery 是否也处理重定向?不确定)。res.redirect() 是实际的 HTTP 响应,而不是像在 ASP.NET 中那样将请求重新路由到另一条路由的内部服务器端指令(实际上这是错误的)......路由旨在接收请求,回复并忘记它。您需要将路由与处理它们的实际函数分开,然后您将能够调用该函数而不是发送重定向。
Code suggestions
代码建议
In app.del('/team/:key' ...
在 app.del('/team/:key' ...
...
retStatus = 'Success';
// res.redirect('/team');
res.send({
retStatus : retStatus,
redirectTo: '/team',
msg : 'Just go there please' // this should help
});
...
Client-side in $.post('/team/' ...
客户端在 $.post('/team/' ...
...
$.post('/team/' + teamId, { _method : 'delete' }, function(response) {
console.log(response);
if(response.retStatus === 'Success') {
// not sure what did you mean by ('/team' && '/team' !== "")
// if('/team' && '/team' !== "") {
if (response.redirectTo && response.msg == 'Just go there please') {
window.location = response.redirectTo;
}
}
});
...
Not sure it will work though because I don't understand what your getAllTeams
does and why you store teamList
in req. If you want to store in session, than assuming the middleware is correctly configured you need to use req.session. If you need to store it only within request and your getAllTeams prepares this list of teams it is better to store in res.locals (like res.locals.teamList).
And make sure your getAllTeams calls next. So basically your getAllTeams should look like this:
不确定它会起作用,因为我不明白你getAllTeams
做什么以及你为什么存储teamList
在 req. 如果您想在会话中存储,那么假设中间件配置正确,您需要使用 req.session。如果您只需要将其存储在请求中并且您的 getAllTeams 准备此团队列表,则最好将其存储在 res.locals(如 res.locals.teamList)中。并确保您的 getAllTeams 接下来调用。所以基本上你的 getAllTeams 应该是这样的:
function getAllTeams (req, res, next) {
res.locals.teamList = [/* whatever */];
next();
}
And then you can use res.locals.teamList in your route handler instead of req.teamList.
然后您可以在路由处理程序中使用 res.locals.teamList 而不是 req.teamList。
res.render('team', {teamsList : res.locals.teamsList} );
And 'team' template also can have a problem...
而且“团队”模板也可能有问题......
Express advice :)
明确的建议:)
Also the way you use Express makes it very difficult to extend/manage application. I don't remember where exactly, but somewhere in docs they write that Express is supposed to be used as the foundation for your application framework, not as a complete framework like most PHP frameworks are. It gives you a lot of power and flexibility, but also makes it necessary to think about your application architecture well in advance.
此外,您使用 Express 的方式使得扩展/管理应用程序变得非常困难。我不记得具体在哪里,但在他们写的文档中的某个地方,Express 应该用作应用程序框架的基础,而不是像大多数 PHP 框架那样作为一个完整的框架。它为您提供了强大的功能和灵活性,但也使您有必要提前考虑您的应用程序架构。
The most powerful feature of express is that you can have any route handled by many route-specific handlers/middlewares passing control to each other via next(). I have a static table that defines which handlers are used on each route allowing to see the whole application with 30 or so routes on one page. And this table is used to assemble the routing dynamically when the application starts. It leads to a lot of flexibility, manageability (I can move/copy-paste handlers from route to route - each handler is represented as a single word) and code re-use. I also use the same hash of routes definition in the client for client-side routing.
express 最强大的功能是您可以让许多特定于路由的处理程序/中间件处理任何路由,这些处理程序/中间件通过 next() 相互传递控制权。我有一个静态表,它定义了在每个路由上使用哪些处理程序,允许在一页上查看具有 30 个左右路由的整个应用程序。并且该表用于在应用程序启动时动态组装路由。它带来了很大的灵活性、可管理性(我可以在路由之间移动/复制粘贴处理程序——每个处理程序都表示为一个单词)和代码重用。我还在客户端中使用相同的路由定义散列进行客户端路由。
回答by Tutan Ramen
For a quick workaround, just add the redirect url to the response and on the client side do:
要快速解决方法,只需将重定向 url 添加到响应中,然后在客户端执行:
if (redirectUrl && redirectUrl !== "")
window.location = redirectUrl;