是否有可能为NodeJS应用程序设置一个基本的URL?
我希望能够在同一个域下托pipe多个NodeJS应用程序,而无需使用子域(如google.com/reader而不是像images.google.com)。 问题是我总是在Express / NodeJS中inputurl的第一部分,比如“/ reader”。
我如何设置一个快速应用程序,使基地址是something.com/myapp
?
所以,而不是:
app.get("/myapp", function (req, res) { // can be accessed from something.com/myapp });
我可以:
// Some set-up app.base = "/myapp" app.get("/", function (req, res) { // can still be accessed from something.com/myapp });
我还想configuration连接的staticProvider行为相同的方式(现在默认为静态文件提供到something.com/js
或something.com/css
而不是something.com/js
/ myapp / js)
目前这还不被支持,要自行添加并不容易。
整个路由的东西都埋在服务器代码的深处,作为奖励,他们没有暴露自己的路线。
我通过源代码挖掘出来,也检出了最新版本的Express和Connect中间件,但是仍然不支持这种function,您应该在Connect或Express本身上打开一个问题。
与此同时…
自己修补这个东西,这里有一个简单快捷的方法,只需更改一行代码即可。
在~/.local/lib/node/.npm/express/1.0.0/package/lib/express/servers.js
,search:
// Generate the route this.routes[method](path, fn);
这应该在357
行左右,取而代之的是:
// Generate the route this.routes[method](((self.settings.base || '') + path), fn);
现在只需添加设置:
app.set('base', '/myapp');
这对正常string的path工作正常,对于RegEx支持,您必须自己在路由器中间件中进行破解,在这种情况下更好地解决问题。
就静态提供者而言,只需在设置时添加/mypapp
。
更新
使之与RegExp一起工作:
// replace this.routes[method](baseRoute(self.settings.base || '', path), fn); // helper function baseRoute(base, path) { if (path instanceof RegExp) { var exp = RegExp(path).toString().slice(1, -1); return new RegExp(exp[0] === '^' ? '^' + base + exp.substring(1) : base + exp); } else { return (base || '') + path; } }
我只用一些expression式来testing这个,所以这不是100%testing,但理论上它应该工作。
更新2
提交补丁的问题:
https://github.com/visionmedia/express/issues/issue/478
快速路由器可以从4.0开始处理
http://expressjs.com/api#router
http://bulkan-evcimen.com/using_express_router_instead_of_express_namespace.html
var express = require('express'); var app = express(); var router = express.Router(); // simple logger for this router's requests // all requests to this router will first hit this middleware router.use(function(req, res, next) { console.log('%s %s %s', req.method, req.url, req.path); next(); }); // this will only be invoked if the path ends in /bar router.use('/bar', function(req, res, next) { // ... maybe some additional /bar logging ... next(); }); // always invoked router.use(function(req, res, next) { res.send('Hello World'); }); app.use('/foo', router); app.listen(3000);
以前的答案(express 4.0之前):
express-namespace模块(现在已经死了)用来做这个事情:
https://github.com/visionmedia/express-namespace
require('express-namespace'); app.namespace('/myapp', function() { app.get('/', function (req, res) { // can be accessed from something.com/myapp }); });
现在只需要使用Express.js
v4来更新线程,而不需要使用express-namespace
:
var express = require('express'), forumRouter = express.Router(), threadRouter = express.Router(), app = express(); forumRouter.get('/:id)', function(req, res){ res.send('GET forum ' + req.params.id); }); forumRouter.get('/:id/edit', function(req, res){ res.send('GET forum ' + req.params.id + ' edit page'); }); forumRouter.delete('/:id', function(req, res){ res.send('DELETE forum ' + req.params.id); }); app.use('/forum', forumRouter); threadRouter.get('/:id/thread/:tid', function(req, res){ res.send('GET forum ' + req.params.id + ' thread ' + req.params.tid); }); forumRouter.use('/', threadRouter); app.listen(app.get("port") || 3000);
干杯!
我能够实现这个使用快速命名空间的路线的组合和来自下面的谷歌小组讨论静态资产的修复。 这段代码会将对/foo/javascripts/jquery.js的请求视为对/javascripts/jquery.js的请求:
app.use('/foo', express.static(__dirname + '/public'));
来源: https : //groups.google.com/forum/#! msg/ express- js/ xlP6_DX6he0/6OTY4hwfV-0J
还有可靠性问题。 如果可靠性很重要,常见的解决scheme是使用前端反向HTTP代理,如nginx或HAProxy。 它们都使用单线程均衡架构,因此非常具有可扩展性。
然后,对于不同的子网站,可以拥有不同的节点进程,如果一个站点发生故障(未捕获的exception,内存泄漏,程序员错误等),则其余的子站点将继续工作。
我一直在寻找这个function,但对于API路由,而不是静态文件。 我做的是,当我初始化路由器时,我添加了安装path。 所以我的configuration看起来像这样
//Default configuration app.configure(function(){ app.use(express.compress()); app.use(express.logger('dev')); app.set('json spaces',0); app.use(express.limit('2mb')); app.use(express.bodyParser()); app.use('/api', app.router); // <--- app.use(function(err, req, res, callback){ res.json(err.code, {}); }); });
调用路由器时注意'/ api'
我知道这是一个非常古老的问题,但Express已经改变了很多,因为大多数这些答案都已经发布,所以我想我会分享我的方法。
当然,您可以使用Express 4的路由器将特定path后面的相关function组合在一起。 这是有据可查的,并已被其他答案覆盖。
但是,也可以在特定path上安装整个应用程序。 作为一个例子,假设我们的应用程序(我们想在/myapp
托pipe的应用程序)看起来像这样,在一个名为myapp.js
的文件中:
var express = require('express'), path = require('path'), app = express(); app.use(express.static(path.join(__dirname, 'public'))); app.get('/hello', function(req, res) { res.send('Hello'); }); // Lots of other stuff here exports.app = app;
在我们的主js文件中,我们可以在path/myapp
挂载这个整个应用程序:
var express = require('express'), app = express(), myApp = require('./myapp').app; app.use('/myapp', myApp); app.listen(3000);
请注意,我们在这里创build了两个应用程序,一个安装在另一个上。 主应用程序可以根据需要在不同的path上安装更多的子应用程序。
myapp.js
的代码完全独立于它的安装位置。 这与express-generator
在这方面使用的结构相似。
有关子应用程序的一些文档可以在这里find:
https://expressjs.com/en/4x/api.html#app.mountpath https://expressjs.com/en/4x/api.html#app.onmount