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