【发布时间】:2015-08-09 20:05:50
【问题描述】:
我有这个问题,其中配置了一堆 Express 路由,最后一个路径是 /admin。当我从服务器请求任何路径时,只会调用 /admin 路由的回调。
这是我的主要 Node.js 源文件,可以查看如何设置路由:
require('babel/register')({
stage: 0
});
var React = require('react/addons'),
express = require('express'),
bodyParser = require('body-parser'),
path = require('path'),
logger = require('morgan'),
pg = require('pg'),
pgpromise = require('./server/pg-promise'),
Page = require('./ui/js/Page'),
pgrest = require('./server/pgrest'),
App = React.createFactory(require('./ui/js/App'));
const CONNECTION_STRING = 'postgres://foobar:foobar@localhost/postgres';
var app = express();
app.use(bodyParser.json());
app.use(logger('dev'));
app.use(express.static(path.join(__dirname, '..', 'dist')));
app.set('views', path.join(__dirname, 'ui'));
app.set('view engine', 'jade');
pgrest.init(
app,
CONNECTION_STRING
).then(function(api) {
// React server-side rendering
for (var pageKey in Page) {
if (Page.hasOwnProperty(pageKey)) {
var page = Page[pageKey];
if (page.serverRendered) {
app.get(page.path, function(req, res) {
console.log(req.path + ' matched ' + page.path);
function render(data) {
var reactHtml = React.renderToString(App({
initialPageName: page.name,
initialPageParams: req.params,
initialPageQuery: req.query,
pageData: data
}));
res.render('index', { reactHtml: reactHtml });
}
if (page.restPath) {
var restFunction = api.get[page.restPath];
if (restFunction) {
restFunction(req).then(render).fail(function(err) {
if (err.status == 401 && !err.loggedIn) {
// Redirect to the login page if the REST status is 401 and the user isn't logged in.
res.redirect('/login');
} else {
// Render the requested page with the error details shown.
res.render('index', {
reactHtml: React.renderToString(App({
initialPageName: page.name,
initialPageParams: req.params,
initialPageQuery: req.query,
notFound: err.status == 404,
notAuthorized: err.status == 401,
unknownError: [401, 404].indexOf(err.status) < 0 ? (err.message || 'An unknown error occurred.') : null
}))
});
}
});
} else {
render();
}
} else {
render();
}
});
}
console.log(page.name + ' => ' + page.path);
}
}
// 404
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
app.listen(3001);
}).fail(function(err) {
console.error('Error: ' + JSON.stringify(err));
});
这里是Page:
module.exports = {
Home: {
name: 'Home',
path: '/',
pageParams: [],
queryParams: [],
clientRendered: true,
serverRendered: true,
component: require('./pages/Home'),
restPath: null,
dataTarget: null
},
Search: {
name: 'Search',
path: '/search',
pageParams: [],
queryParams: ['q'],
clientRendered: true,
serverRendered: true,
component: require('./pages/Search'),
restPath: null,
dataTarget: null
},
Register: {
name: 'Register',
path: '/register',
pageParams: [],
queryParams: [],
clientRendered: true,
serverRendered: true,
component: require('./pages/Register'),
restPath: null,
dataTarget: null
},
Activate: {
name: 'Activate',
path: '/activate',
pageParams: [],
queryParams: ['email', 'code'],
clientRendered: false,
serverRendered: true,
component: require('./pages/Activate'),
restPath: null,
dataTarget: null
},
ForgotPassword: {
name: 'ForgotPassword',
path: '/forgot-password',
pageParams: [],
queryParams: [],
clientRendered: true,
serverRendered: true,
component: require('./pages/ForgotPassword'),
restPath: null,
dataTarget: null
},
ResetPassword: {
name: 'ResetPassword',
path: '/reset-password',
pageParams: [],
queryParams: ['email', 'code'],
clientRendered: false,
serverRendered: true,
component: require('./pages/ResetPassword'),
restPath: null,
dataTarget: null
},
Login: {
name: 'Login',
path: '/login',
pageParams: [],
queryParams: [],
clientRendered: true,
serverRendered: true,
component: require('./pages/Login'),
restPath: null,
dataTarget: null
},
Profile: {
name: 'Profile',
path: '/profile',
pageParams: [],
queryParams: [],
clientRendered: true,
serverRendered: true,
component: require('./pages/Profile'),
restPath: '/api/1/profile',
dataTarget: 'profile'
},
Member: {
name: 'Member',
path: '/member/:id',
pageParams: ['id'],
queryParams: [],
clientRendered: true,
serverRendered: true,
component: require('./pages/Member'),
restPath: '/api/1/member/:id',
dataTarget: 'member'
},
Inbox: {
name: 'Inbox',
path: '/inbox',
pageParams: [],
queryParams: [],
clientRendered: true,
serverRendered: true,
component: require('./pages/Inbox'),
restPath: null,
dataTarget: null
},
Administration: {
name: 'Administration',
path: '/admin',
pageParams: [],
queryParams: [],
clientRendered: true,
serverRendered: true,
component: require('./pages/Administration'),
restPath: null,
dataTarget: null
}
};
当我启动 Node 应用程序时,我得到以下输出:
Home => /
Search => /search
Register => /register
Activate => /activate
ForgotPassword => /forgot-password
ResetPassword => /reset-password
Login => /login
Profile => /profile
Member => /member/:id
Inbox => /inbox
Administration => /admin
当我在浏览器中访问一个页面时,我会得到这个控制台输出:
/ matched /admin
这显然是不正确的。
知道这里发生了什么吗?
【问题讨论】:
-
这里是在黑暗中拍摄的,但看起来您并没有在点击页面后结束您的请求。循环继续。尝试使用 return 语句或 res.send 或类似的方式。
-
for循环仅在服务器启动时迭代一次,之后pgrest组件已初始化。 -
与您的问题无关,只是在您的代码上:当您包含
pg-promise时,也不要包含pg,因为pg-promise公开了它通过属性pg使用的pg初始化后,即require('pg-promise')(/*options*/).pg. -
这实际上是我自己的小图书馆,而不是this one。话虽如此,
pg是一个旧的require,我还没来得及删除。而pg-promise本身也不再在主js文件中使用。这一切都包含在pgrest(我的另一个小图书馆)中。
标签: javascript node.js express