所以我开始使用Node.js.我在Nodejs.org看了Ryan Dahl的视频,听说他为网站推荐了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
错误。
有谁可以向我解释我在这里缺少什么? - 谢谢。
答案 0 :(得分:74)
因此,在我创建问题之后,我在右边的相关列表中出现了类似的问题:Organize routes in Node.js。
该帖子中的答案与Express repo on GitHub相关联,并建议查看“route-separation”示例。
这帮助我改变了我的代码,现在我已经开始工作了。 - 感谢您的评论。
我的实施最终看起来像这样;
我在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
})
}
答案 1 :(得分:10)
route-map表达示例将url路径与对象匹配,而对象又将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);
答案 2 :(得分:5)
似乎只在需要时加载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];
}
});
答案 3 :(得分:4)
您也可以将它们组织成模块。所以它就像是。
./
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;
};
然后在controller dir的index.js中
exports.indexController = require("./indexController");
最后在app.js
var controllers = require("./controllers");
app.get("/",controllers.indexController().indexAction);
我认为这种方法可以更清晰地分离,也可以通过传递数据库连接来配置控制器。
答案 4 :(得分:1)
花费时间调用/定义路由根本没有任何意义。即使您确实需要自定义控件,也可能只在某些时间,并且在大多数情况下,您希望能够仅创建路由的标准文件结构并让模块自动执行。
在扩展应用程序时,路由调用将开始形成一堆毫无用处的代码。您只需要执行两行代码即可使用Route Magic处理所有app.use
路由调用,如下所示:
const magic = require('express-routemagic')
magic.use(app, __dirname, '[your route directory]')
对于那些想要手动处理的用户,只是不要使用将目录传递给Magic。