2

在我的快速应用,由于某种原因,所有路由都返回404Expressjs - 所有路线404

Server.js

/** 
* Module dependencies 
*/ 

var express = require('express') 
var passport = require('passport') 
var env = process.env.NODE_ENV || 'development' 
var config = require('./config/config')[env] 
var mongoose = require('mongoose') 
var fs = require('fs') 

require('./helpers') 
require('express-namespace') 

mongoose.connect(config.db) 

// Bootstrap models 
fs.readdirSync(__dirname + '/app/models').forEach(function (file) { 
    if (~file.indexOf('.js')) require(__dirname + '/app/models/' + file) 
}) 

// Bootstrap passport config 
require('./config/passport')(passport, config) 

var app = express() 

// Bootstrap application settings 
require('./config/express')(app, config, passport) 

// Bootstrap routes 
require('./config/routes')(app, passport) 

// Start the app by listening on <port> 
var port = config.port || process.env.PORT || 3000 
app.listen(port) 
console.log('Express app started on port '+port) 

// Expose app 
module.exports = app 

Routes.js

/** 
* Module dependencies. 
*/ 

var mongoose = require('mongoose') 
var passportOptions = { 
    failureFlash: 'Invalid email or password.', 
    failureRedirect: '/login' 
} 

// controllers 
var home = require('home') 
var functions = require('function') 

/** 
* Expose 
*/ 

module.exports = function (app, passport) { 

    console.log("SR"); 
    app.get('/', function(req,res){ 
    console.log("//////"); 
    }) 
    app.get('/functions/get',functions.get) 
    app.post('/functions/submit',functions.sub) 
    app.get('/login',passport.authenticate('google',{ 
    "scope":"https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile", 
    "hd":"kinokiapp.com" 
    })) 
    app.get('/google/callback',passport.authenticate('google', { failureRedirect:"/" }),function(req,res){ 
    res.end("auth") 
    }) 

console.log("ER"); 
} 

Home.js

/*! 
* Module dependencies. 
*/ 

console.log("HIH"); 

exports.index = function (req, res) { 
    res.render('home', { 
    title: 'Node Express Mongoose Boilerplate' 
    }) 
} 

function.js

var mongoose = require('mongoose') 

var KIFunction = mongoose.model("KIFunction") 

exports.get = function(req, res) { 
    res.type('text/kinoki-function') 
    res.status(200); 
    var exclude 
    try { 
     exclude = JSON.parse(req.query.n) 
    } catch (e) { 
     exclude = [] 
    } 
    for (var i = 0; i < exclude.length; i++) { 
     if (typeof exclude[i] != 'string') { 
      continue; 
     } 
     exclude[i] = mongoose.Types.ObjectId(exclude[i]) 
    } 
    KIFunction.random({ 
     "_id":{ 
      "$nin":exclude 
     }, 
     approved1:true, 
     approved2:true, 
    }).limit(10).exec(function(err,functions){ 
     if (err || functions.length == 0) {return res.end("false")} 
     var out = '' 
     functions.forEach(function(f){ 
      out += "{0}#{1}#{2}#{3}|".format(f.steps, f.string, f.difficulty, f._id) 
     }) 

     res.end(out.substring(0, out.length - 1),"utf8") 
    }) 
} 


exports.sub = function(req,res){ 
    var fstr = req.body.str 
    if (!(req.body.hasOwnProperty("str")) || !(fstr.match(KIFunction.functionRegex()))) { 
     res.status(400) 
     res.end("false") 
     return 
    } 

    new KIFunction({ 
     string:fstr 
    }).save(function(err){ 
     if(err) { 
      res.status(200) 
      return res.end("false") 
     } 
     res.status(200) 
     res.end("true") 
    }) 
} 

输出为:

8月23日8点21分16秒 - [nodemon]开始node server.js HIH SR ER 快速应用启动3000端口 GET/404 571ms - 器863b

配置/ config.js

/*! 
* Module dependencies. 
*/ 

var path = require('path') 
var rootPath = path.resolve(__dirname + '../..') 

/** 
* Expose config 
*/ 

module.exports = { 
    development: { 
    root: rootPath, 
    db: 'mongodb://localhost/kinoki_dev', 
    rootURL:"http://localhost/", 
    logger: 'dev' 
    }, 
    test: { 
    root: rootPath, 
    db: 'mongodb://localhost/kinoki_test', 
    rootURL:"http://localhost/", 
    port: 9273, 
    logger: false 
    }, 
    ci: { 
    root: rootPath, 
    db: ("mongodb://" + process.env.WERCKER_MONGODB_HOST + ":" + process.env.WERCKER_MONGODB_PORT + "/kinoki_ci"), 
    port: 2547, 
    rootURL:"http://localhost/", 
    logger: false 
    }, 
    production: { 
    root: rootPath, 
    dbpass:"xyz", 
    db: 'mongodb://user:[email protected]:39768/kinoki', 
    rootURL:"http://kinokiapp.com/", 
    logger: 'dev' 
    } 
} 

配置/ express.js

/*! 
* Module dependencies. 
*/ 

var express = require('express') 
var mongoStore = require('connect-mongo')(express) 
var helpers = require('view-helpers') 
var pkg = require('../package') 
var flash = require('connect-flash') 
var env = process.env.NODE_ENV || 'development' 
var config = require("./config")[env] 

/*! 
* Expose 
*/ 

module.exports = function (app, config, passport) { 
    // Add basic auth for staging 
    if (env === 'staging') { 
    app.use(express.basicAuth(function(user, pass){ 
     return 'username' == user & 'password' == pass 
    })) 

    app.use(function (req, res, next) { 
     if (req.remoteUser && req.user && !req.user._id) { 
     delete req.user 
     } 
     next() 
    }) 
    } 

    app.set('showStackError', true) 

    // use express favicon 
    app.use(express.favicon(config.root + '/public/favicon.ico')) 

    app.use(express.static(config.root + '/public')) 
    if(config.logger){ 
    app.use(express.logger(config.logger)) 
    } 

    // views config 
    app.set('views', config.root + '/app/views') 
    app.set('view engine', 'jade') 

    app.configure(function() { 
    // bodyParser should be above methodOverride 
    app.use(express.bodyParser()) 
    app.use(express.methodOverride()) 

    // cookieParser should be above session 
    app.use(express.cookieParser()) 
    app.use(express.session({ 
     secret: pkg.name, 
     store: new mongoStore({ 
     url: config.db, 
     collection : 'sessions' 
     }) 
    })) 

    // Passport session 
    app.use(passport.initialize()) 
    app.use(passport.session()) 

    // Flash messages 
    app.use(flash()) 

    // expose pkg and node env to views 
    app.locals({ 
     pkg:pkg, 
     env:env 
    }) 

    // View helpers 
    app.use(helpers(pkg.name)) 

    // routes should be at the last 
    app.use(app.router) 

    // custom error handler 
    app.use(function (err, req, res, next) { 
     if (err.message 
     && (~err.message.indexOf('not found') 
     || (~err.message.indexOf('Cast to ObjectId failed')))) { 
     return next() 
     } 

     console.error(err.stack) 
     res.status(500).render('500') 
    }) 

    app.use(function (req, res, next) { 
     res.status(404).render('404', { url: req.originalUrl }) 
    }) 
    }) 

    // development specific stuff 
    app.configure('development', function() { 
    app.locals.pretty = true; 
    }) 

    // staging specific stuff 
    app.configure('staging', function() { 
    app.locals.pretty = true; 
    }) 
} 

配置/ passport.js

/*! 
* Module dependencies. 
*/ 

var mongoose = require('mongoose') 
var GoogleStrategy = require('passport-google-oauth').OAuth2Strategy 
var User = mongoose.model('User') 
var config = require('./config')[process.env.NODE_ENV] 

/** 
* Expose 
*/ 

module.exports = function(passport, config) { 
    // serialize sessions 
    passport.serializeUser(function(user, done) { 
    done(null, user.id) 
    }) 

    passport.deserializeUser(function(id, done) { 
    User.findOne({ 
     _id: id 
    }, function(err, user) { 
     done(err, user) 
    }) 
    }) 

    passport.use(new GoogleStrategy({ 
    clientID: process.env.GOOGLE_ID, 
    clientSecret: process.env.GOOGLE_SECRET, 
    callbackURL: config.rootURL + 'google/callback' 
    }, 
    function(accessToken, refreshToken, profile, done) { 
    User.findOne({ 
     id: profile.id 
     }, function(err, user) { 
     if (err) { 
      return done(err) 
     } 
     if (!user) { 
      user = new User({ 
      id: profile.id, 
      profile: profile, 
      accessToken:accessToken, 
      refreshToken:refreshToken 
      }) 
      user.save(function(err) { 
      if (err) { 
       return done(err) 
      } 
      done(null, user) 
      }) 
     } else { 
      done(null,user) 
     }  
     }) 
    } 
)) 

    passport.reqAuth = function(req,res,next){ 
    if(req.isAuthenticated()) 
     return next() 
    else 
     res.redirect('/login') 
    } 
} 

配置/ routes.js

/** 
* Module dependencies. 
*/ 

var mongoose = require('mongoose') 
var passportOptions = { 
    failureFlash: 'Invalid email or password.', 
    failureRedirect: '/login' 
} 

// controllers 
var home = require('home') 
var functions = require('function') 

/** 
* Expose 
*/ 

module.exports = function (app, passport) { 

    console.log("SR"); 
    app.get('/', function(req,res){ 
    console.log("//////"); 
    }) 
    app.get('/functions/get',functions.get) 
    app.post('/functions/submit',functions.sub) 
    // app.get('/login',passport.authenticate('google',{ 
    // "scope":"https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile", 
    // "hd":"kinokiapp.com" 
    // })) 
    // app.get('/google/callback',passport.authenticate('google', { failureRedirect:"/" }),function(req,res){ 
    // res.end("auth") 
    // }) 

console.log("ER"); 
} 

有谁知道为什么所有的路由都返回404(所有的他们是404,我只是没有日志)。

如果您需要更多代码,请让我知道。

回答

7

如果请求到达中间件链的末尾而没有任何发送响应,则表示404。所以一个常见的原因是缺少app.use(app.router)

您的情况passport.deserializeUser(id, fn)passport.session()内引发错误。 Express将请求直接传递给您的自定义错误处理程序,绕过app.router。由于错误不是“未找到”,因此会导致404

如果User.findOne(...未找到用户,我可能会返回null的用户。您需要确保向登录用户和未登录用户显示的任何模板处理这两种情况。

而且我经常用这个,它可能会派上用场:

function restrictToLoggedIn(req, res, next){ 
    if(req.user && req.user !== null){ 
    return next() 
    } else { 
    res.send(401, 'Must be logged in'); 
    }; 
}; 

app.get('/' 
, restrictToLoggedIn 
, function(req, res, next){ 
// req.user is guranteed to be populated 
    res.locals.user = req.user; 
    res.render('home'); 
}); 

编辑:为后人留下排查...

如果app.use(app.router)./config/express,检查已存在以前的中间件。您可以在路线顶部设置一条超级路线。JS以确保任何撞击路由器发送200:app.all('*', function(req,res){ res.send(200, req.originalUrl) });

最后,确认require('function')正确加载。我总是用require('./function.js')

您可以将您的app.use(passport...中间件功能注释掉以测试是否有问题。

如果这一切都没有帮助,请发布您的config/* javascript文件。

+0

对不起,没有工作,但很好的解决方案。我在config/*中发布了代码。 –

+0

我的下一步是定义一个自定义的中间件函数,如'var testResponse = function(req,res){res.send(200,req.originalUrl)};'然后将'app.use(testResponse)'放在您的中间件链的顶部。继续沿着链向下移动,直到响应404来识别问题中间件 – Plato

+0

哦,我刚刚注意到,至少'/'没有发送响应,这将使得它成为404.出现'routes.get'和'routes.sub'尽管发送回应。 – Plato