Expressjs - 所有路由都是 404
Posted
技术标签:
【中文标题】Expressjs - 所有路由都是 404【英文标题】:Expressjs - All Routes Are 404 【发布时间】:2013-08-26 17:27:02 【问题描述】:在 My Express App 中,由于某种原因,所有路线都返回 404。
服务器.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'
)
函数.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 日 08:21:16 - [nodemon] 开始
node server.js
HIH SR ER Express 应用程序在端口 3000 上启动 GET / 404 571ms - 863b
config/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:pass@mymongoserver.com:39768/kinoki',
rootURL:"http://kinokiapp.com/",
logger: 'dev'
config/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')
config/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,我只是没有日志)。
如果您需要更多代码,请告诉我。
【问题讨论】:
【参考方案1】:如果请求到达中间件链的末尾而没有任何响应,则表示 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
中,请检查之前的中间件。您可以在您的 routes.js 顶部设置一个包罗万象的路由,以确保任何命中路由器的东西都会发送 200:app.all('*', function(req,res) res.send(200, req.originalUrl) );
最后,确认require('function')
正在正确加载。我总是使用require('./function.js')
。
你可以注释掉你的app.use(passport...
中间件函数来测试是否有问题。
如果这些都没有帮助,请发布您的 config/*
javascript 文件。
【讨论】:
抱歉,这不起作用,但很好的解决方案。我在 config/* 中发布了代码。 我的下一步是定义一个自定义中间件函数,例如var testResponse = function(req,res) res.send(200, req.originalUrl) ;
,然后将 app.use(testResponse)
放在中间件链的顶部。继续沿链向下移动,直到响应 404 来识别问题中间件
哦,我刚刚注意到至少 /
没有发送响应,这将使其变为 404。routes.get
和 routes.sub
似乎发送响应。
看起来任何无法匹配路由的请求都应该传递给您的自定义错误处理程序。当您访问页面时,该页面是否按预期呈现您的 404
和 500
模板?还是只发送 404 代码?
非常感谢!我遇到了同样的问题。在您的解释之后,我发现并解决了 deserializUser 中的问题以上是关于Expressjs - 所有路由都是 404的主要内容,如果未能解决你的问题,请参考以下文章
如何将 404 错误重定向到 ExpressJS 中的页面?