在Express-js中使用路由
所以我开始使用Node.js. 我在Nodejs.org上看到Ryan Dahl的video,听说他推荐Express-js用于网站。
我下载了最新版本的Express,并开始编码。 我有一个完全成熟的静态视图/,但只要我尝试发送参数,我得到像这样的错误:
Cannot GET /wiki
我尝试遵循expressjs.com上的指南,但最新版本中使用路线的方式已经更改,导致指南无法使用。
指南:
app.get('/users/:id?', function(req, res, next){ var id = req.params.id; if (id) { // do something } else { next(); } });
Express生成:
app.get('/', routes.index);
我尝试添加另一条路线时出现问题。
app.get('/wiki', routes.wiki_show);
我已经尝试了一堆方法,但我一直得到Cannot GET /wiki
(404)错误。
routes / index.js看起来像这样:
exports.index = function(req, res) { res.render('index', { title: 'Test', articles: articles, current_article: current_article, sections: sections }) };
我在那里做的唯一的事情是添加一些参数(在同一个文件中的数组),这个我工作。 但是,当我复制的内容并将exports.index
更改为exports.wiki
或exports.wiki_show
我仍然得到Cannot GET /wiki
错误。
任何人都可以向我解释我在这里失踪? – 谢谢。
所以,在我创build我的问题之后,我得到了与右边相关的列表,类似的问题是: 在Node.js中组织路由 。
这个post的答案与GitHub上的Express回购相关,并build议看看“ 路线分离 ”的例子。
这帮助我改变我的代码,现在我已经可以工作了。 – 感谢您的意见。
我的实现最终看起来像这样;
我需要我的路线在app.js中:
var express = require('express') , site = require('./site') , wiki = require('./wiki');
我添加我的路线是这样的:
app.get('/', site.index); app.get('/wiki/:id', wiki.show); app.get('/wiki/:id/edit', wiki.edit);
我的应用程序根目录中有两个名为wiki.js和site.js的文件,其中包含:
exports.edit = function(req, res) { var wiki_entry = req.params.id; res.render('wiki/edit', { title: 'Editing Wiki', wiki: wiki_entry }) }
路线图expression示例将urlpath与对象进行匹配,而这些对象又将http动词与函数进行匹配。 这将树形结构放在一个简明易读的树中。 应用程序的实体也被写成对象,其函数为封闭的方法。
var express = require('../../lib/express') , verbose = process.env.NODE_ENV != 'test' , app = module.exports = express(); app.map = function(a, route){ route = route || ''; for (var key in a) { switch (typeof a[key]) { // { '/path': { ... }} case 'object': app.map(a[key], route + key); break; // get: function(){ ... } case 'function': if (verbose) console.log('%s %s', key, route); app[key](route, a[key]); break; } } }; var users = { list: function(req, res){ res.send('user list'); }, get: function(req, res){ res.send('user ' + req.params.uid); }, del: function(req, res){ res.send('delete users'); } }; var pets = { list: function(req, res){ res.send('user ' + req.params.uid + '\'s pets'); }, del: function(req, res){ res.send('delete ' + req.params.uid + '\'s pet ' + req.params.pid); } }; app.map({ '/users': { get: users.list, del: users.del, '/:uid': { get: users.get, '/pets': { get: pets.list, '/:pid': { del: pets.del } } } } }); app.listen(3000);
似乎只有index.js在需要(“./ routes”)时被加载。 我在index.js中使用下面的代码来加载其余的路由:
var fs = require('fs') , path = require('path'); fs.readdirSync(__dirname).forEach(function(file){ var route_fname = __dirname + '/' + file; var route_name = path.basename(route_fname, '.js'); if(route_name !== 'index' && route_name[0] !== "."){ exports[route_name] = require(route_fname)[route_name]; } });
你也可以把它们组织成模块。 所以会是这样的。
./ controllers index.js indexController.js app.js
然后在控制器的indexController.js中导出你的控制器。
//indexController.js module.exports = function(){ //do some set up var self = { indexAction : function (req,res){ //do your thing } return self; };
然后在控制器目录的index.js
exports.indexController = require("./indexController");
最后在app.js中
var controllers = require("./controllers"); app.get("/",controllers.indexController().indexAction);
我认为这种方法允许更清晰的分离,你也可以configuration你的控制器通过传递一个数据库连接。