【问题标题】:Nodejs router orderNodejs路由器顺序
【发布时间】:2017-03-29 05:04:32
【问题描述】:

我正在使用:

表达 4.14 节点 7.0+ 会话 1.14+


我用 webstorm 创建了 Nodejs 项目:

app.js

var express = require('express');
var session = require('express-session');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');

var index = require('./routes/index');
var user = require('./routes/user');

var app = express();

var check = function() {
    !req.session.status ? res.redirect('/user/login') : next();
}

app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');

app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use(session({secret: "inline", resave: false, saveUninitialized: true,     status: false}));

app.use('/', check, require('./routes/index'));
app.use('/user', require('./routes/user'));

module.exports = app;

index.js

var express = require('express');
var router = express.Router();

router.get('/', function(req, res, next) {
    res.render('index', { title: 'Express' });
});

module.exports = router;

user.js

var express = require('express');
var router = express.Router();

router.get('/', function(req, res, next) {
    res.render('index', { title: 'Express' });
});

router.get('/login', function(req, res, next) {
    res.render('login');
});

module.exports = router;

当我请求localhost:3000时,页面提示我“重定向太多”,现在网址是localhost:3000/user/login

我的问题是什么?

【问题讨论】:

  • 这是全部你的代码吗?
  • 请输入您的问题文件来自:./routes/index 也输入整个文件,而不是其中的一部分,因为可能还有其他问题导致它发生。
  • @num8er 我把我所有的代码都放在这里了。
  • 好的,你尝试过我的回答吗?

标签: javascript node.js express


【解决方案1】:

修复:

var check = function(req, res, next) {
    !req.session.status ? res.redirect('/user/login') : next();
}




但是我会为你写更漂亮的解决方案,希望你能明白:

app.js:

app.use(require('./routes'));

routes文件夹:

routes/
 |- index.js
 |- common/
    |- auth.js
 |- root/
    |- index.js
    |- posts.js
 |- backend/
    |- index.js
    |- posts.js
    ...

1)routes/index.js

const
  express = require('express'),
  router = express.Router();

// guarded routes
function guardFn(req, res, next) {
  let authenticated = req.session && req.session.authenticated === true;
  authenticated ? next() : res.redirect('/auth');
}
router.use('/backend', guardFn, require('./backend'));

// public routes
router.use('/auth', require('./common/auth'); // for auth purposes
router.use('/', require('./root')); // for routes that starts from /, try not to rewrite /backend, /auth

module.exports = router;

2)routes/common/auth

const
  express = require('express'),
  router = express.Router();
  mongoose = require('mongoose'),
  User = mongoose.model('user');

router.get('/', (req, res) => {
  res.render('common/auth');
});

router.post('/', (req, res) => {
  User
    .findOne({
      username: req.body.username, 
      password: req.body.password
    })
    .exec((err, user) => {
      if(err) {
        console.error(err);
        return res.status(500).send('System error! Try again later');
      }
      if(!user) return res.redirect('back');
      req.session.user = user._id;
      req.session.authenticated = true;
      res.redirect('/backend');
    });
});

function logout(req, res, next) {
  delete req.session.user;
  req.session.authenticated = false;
  next();
}
router.delete('/auth', logout, (req, res) => res.send({success: true}));
router.get('/auth/destroy', logout, res => res.redirect('/auth'));

module.exports = router;

3)routes/root/index.js

const
  express = require('express'),
  router = express.Router();

router.get('/', (req, res) => {
  res.render('site/welcome');
});

module.exports = router;

4)routes/root/posts.js

const
  express = require('express'),
  router = express.Router(),
  mongoose = require('mongoose'),
  Post = mongoose.model('post');

router.get('/', (req, res) => {
  Post
    .find()
    .skip((req.query.page-1)*10)
    .limit(10)
    .exec((err, posts) => {
      res.render('site/posts/list', {posts});
    });
});

router.get('/:id', (req, res) => {
  Post
    .findById(req.params.id)
    .exec((err, post) => {
      if(err) {
        console.error(err);
        return res.status(500).send('System error! Try again later');
      }
      res.render('site/posts/show', {post});
    });
});

module.exports = router;

5)routes/backend/index.js

const
  express = require('express'),
  router = express.Router();

router.get('/', (req, res) => {
  res.render('backend/dashboard');
});

module.exports = router;

6)routes/backend/posts.js

const
  _ = require('lodash'),
  express = require('express'),
  router = express.Router(),
  mongoose = require('mongoose'),
  Post = mongoose.model('post');

router.get('/', (req, res) => {
  Post
    .find()
    .skip((req.query.page-1)*50)
    .limit(50)
    .exec((err, posts) => {
      res.render('backend/posts/list', {posts});
    });
});

router.get('/:id', (req, res) => {
  Post
    .findById(req.params.id)
    .exec((err, post) => {
      if(err) {
        console.error(err);
        return res.status(500).send('System error! Try again later');
      }
      res.render('backend/posts/show', {post});
    });
});

function updatePost(id, data, callback) {
  Post
    .findById(_id)
    .exec((err, post) => {
      if(err) return callback(err);
      if(!post) return callback('not found');

      post = _.extend(post, data);
      post.save(() => callback(null, post));
    });
}
router.put('/:id', (req, res) => {
  updatePost(req.params.id, req.body, (err, post) => {
    if(err) return res.status(500).send({success: false, err});
    res.send({success: true, post});
  });
});

router.post('/:id', (req, res) => {
  updatePost(req.params.id, req.body, (err, post) => {
    if(err) return res.status(500).send(err);
    res.redirect('/backend/posts');
  });
});

function createPost(data, callback) {
  let post = new Post();
  post = _.extend(post, req.body);
  post.save((err) => callback(err, post));
}
router.post('/', (req, res) => {
  createPost(req.body, (err, post) => {
    if(req.xhr) {
      if(err) return res.status(500).send({success: false, err});
      return res.send({success: true, post});
    }
    if(err) return res.status(500).send(err);
    res.redirect('/backend/posts');
  });
});

module.exports = router;

【讨论】:

  • 我有办法解决它,但我想知道结果。如果我将app.use('/', index) 更改为app.use('/index', index),同时将router.get('/', (...)=>{...}) 更改为router.get('/index', (...)=> {...}) 并且我请求'localhost:3000/index',它将更改为'localhost:3000/user/login' 而没有@987654342 @所以我想知道为什么'/'会告诉我'重定向太多'
【解决方案2】:

据我了解,app.use('/', ...) 将匹配所有请求,这就是为什么要为所有请求调用 check 方法的原因。

More good info here.

来自 Express 文档:

路由将匹配紧随其路径的任何路径 “/”。

例如:app.use("/apple", ...) 将匹配“/apple”, “/apple/images”、“/apple/images/news”等等。

我建议重构为:

var check = function(req, res, next) {
  if (!req.session.status && req.path != '/user/login') {
    res.redirect('/user/login');
  }
  else {
    next();
  }
}

app.use(check);
app.use('/', index);
app.use('/user', users);

所以check 将对所有请求执行,但仅在请求会话错误且请求路径与/user/login 不匹配时才会重定向

请记住,如果未设置 req.session,您的代码将失败...

【讨论】:

  • :D,所以它不像REX匹配,'/user'会匹配'/''/user',对吧?似乎没有灵活性......但是呃......无论如何
猜你喜欢
  • 2014-04-14
  • 2018-12-23
  • 2018-09-27
  • 2015-12-12
  • 1970-01-01
  • 2017-04-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多