【问题标题】:Expressjs / Node.js - res.redirect() not loading pageExpressjs / Node.js - res.redirect() 未加载页面
【发布时间】:2013-03-10 11:56:47
【问题描述】:

我有一个页面,其路由 GET /team 正在加载团队列表,DEL /team 正在从 /team/:key 中删除团队。因此,您导航到团队的个人资料页面并从那里删除它们,删除时它应该将您重定向到 /team 页面。我已将日志放入控制台,它成功删除了team,奇怪的是,它说它正在加载/team,但浏览器没有加载它。我已经把我的代码放在下面了,有什么想法吗?

路线:

  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 模板:

        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';
                        }
                    }
                });
            });

控制台日志:

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.statics.getAll = function(cb){
    var query = this.find({});
    query.sort({key : -1});
    return query.exec(cb);
  };

【问题讨论】:

  • /team GET 路由需要一个参数 req.teamsList 来呈现页面。它是否在重定向中可用?
  • @almypal 如果我像渲染/team 页面时那样在重定向中添加{'teamsList' : req.teamsList},并添加getAllTeams,控制台中不会显示任何内容,也不会加载任何内容.
  • 如何将其添加到重定向中?
  • @almypal 我尝试添加res.render('team', {'teamsList' : req.teamsList} );,但没有加载任何内容,我认为它不适用于res.render,但它也不适用于简单的重定向,因为它需要一个teamList正如你所说,知道如何解决这个问题吗?
  • /team GET 路由是否独立工作...如果是,参数如何随请求一起发送...

标签: javascript node.js mongoose express


【解决方案1】:

您的请求是 POST ($.post),而您的路由是 app.del,因此它永远不会到达 app.del 路由中的 res.redirect。

为什么不使用 app.post?

更新:

假设 $.post 在这里发送 HTTP DEL 请求发生了什么:服务器发送没有数据的 302 响应,但浏览器从不向 GET 路由发送另一个请求,因为服务器指示它(或者 jQuery 是否也处理重定向?不确定)。 res.redirect() 是实际的 HTTP 响应,而不是一些内部服务器端指令,用于将请求重新路由到另一个路由,就像您在 ASP.NET 中可以做的那样(实际上这是错误的)......路由旨在接收请求,回复回复并忘记它。您需要将路由与处理它们的实际函数分开,然后您将能够调用该函数而不是发送重定向。

代码建议

在 app.del('/team/:key' ...

...
    retStatus = 'Success';
    // res.redirect('/team');
    res.send({
      retStatus : retStatus,
      redirectTo: '/team',
      msg : 'Just go there please' // this should help
    });
...

客户端在 $.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;
            }
        }
    });
...

不确定它是否会起作用,因为我不明白您的 getAllTeams 做了什么以及为什么将 teamList 存储在 req.如果你想存储在 session 中,而不是假设中间件配置正确,你需要使用 req.session。如果您只需要在请求中存储它并且您的 getAllTeams 准备了此团队列表,则最好将其存储在 res.locals(如 res.locals.teamList)中。 并确保您的 getAllTeams 接下来调用。所以基本上你的 getAllTeams 应该是这样的:

function getAllTeams (req, res, next) {
    res.locals.teamList = [/* whatever */];
    next();
}

然后您可以在路由处理程序中使用 res.locals.teamList 而不是 req.teamList。

res.render('team', {teamsList : res.locals.teamsList} );

而且“团队”模板也可能有问题...

表达建议 :)

此外,您使用 Express 的方式也使得扩展/管理应用程序变得非常困难。我不记得确切的位置,但是他们在文档中的某个地方写道,Express 应该用作您的应用程序框架的基础,而不是像大多数 PHP 框架那样作为一个完整的框架。它为您提供了强大的功能和灵活性,但也使您有必要提前考虑您的应用程序架构。

express 最强大的功能是您可以让许多路由特定的处理程序/中间件处理任何路由,并通过 next() 将控制权传递给彼此。我有一个静态表,它定义了在每条路由上使用哪些处理程序,允许在一页上查看整个应用程序,其中包含 30 条左右的路由。并且该表用于在应用程序启动时动态组装路由。它带来了很大的灵活性、可管理性(我可以在路由之间移动/复制粘贴处理程序 - 每个处理程序都表示为一个单词)和代码重用。我还在客户端中使用相同的路由定义哈希进行客户端路由。

【讨论】:

  • 他正在使用可能在服务器上有methodOverride的_method。
  • 我只是尝试将其设为 app.post 而不是 app.del 并从 HTML 页面上的 JS 中删除 _method: delete,但它仍然表示在控制台上路由到 /team,但没有加载在浏览器上。也感谢您的明确建议,我一定会考虑到这一点。
  • @RoelvanUden 正确,我正在使用这个。
  • @esp: _method 是 Connect for NodeJS 提供的 methodOverride 中间件允许的字段。
  • @RoelvanUden 明白了,谢谢。虽然我仍然不明白为什么在你可以使用 app.post 来处理发布请求时使用这个中间件......只有当你有一些移动应用程序使用的工作 API 并且你不想使用 DEL 时浏览器,但不是在您从头开始开发时...
【解决方案2】:

为了快速解决方法,只需将重定向 url 添加到响应中,然后在客户端执行:

if (redirectUrl && redirectUrl !== "")
    window.location = redirectUrl;

【讨论】:

  • 所以将每个redirectUrl 替换为/team 你在说什么?
  • 仍然不能让它工作,你能看看你是否能看到 HTML 代码有什么问题吗?
  • 当我进入 stackoverflow.com 上的控制台并运行 window.location = "/hello";它带我到 stackoverflow.com/hello
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-08
  • 1970-01-01
  • 2014-09-26
相关资源
最近更新 更多