簡體   English   中英

Expressjs / Node.js - res.redirect()沒有加載頁面

[英]Expressjs / Node.js - res.redirect() not loading page

我有一個路由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);
  };

要快速解決方法,只需將重定向url添加到響應中,並在客戶端執行:

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

你的請求是POST($ .post),你的路由是app.del,所以它永遠不會到app.del路由中的res.redirect。

你為什么不用app.post?

更新:

假設$ .post在這里發送HTTP DEL請求發生了什么:服務器發送302響應沒有數據但是瀏覽器從不向GET路由發送另一個請求,因為服務器指示它(或者jQuery處理重定向嗎?不確定)。 res.redirect()是實際的HTTP響應,而不是一些內部服務器端指令,用於將請求重新路由到另一條路徑,就像在ASP.NET中可以做的那樣(實際上是錯誤的)... Route旨在接收請求,回復回復並忘掉它。 您需要將路由與處理它們的實際函數分開,然后您將能夠調用該函數而不是發送重定向。

代碼建議

在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中。 如果要存儲在會話中,而不是假設正確配置了中間件,則需要使用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個左右的路由。 此表用於在應用程序啟動時動態組合路由。 它帶來了很大的靈活性,可管理性(我可以從路由到路由移動/復制粘貼處理程序 - 每個處理程序表示為一個單詞)和代碼重用。 我還在客戶端使用相同的路由定義哈希來進行客戶端路由。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM