我希望能够在同一域下托管多个nodejs应用程序,而无需使用子域(例如google.com/reader而不是images.google.com)。问题在于,我一直在Express/Nodejs中键入URL EG“/读取器”的第一部分。

我如何设置Express应用程序,以便基本URL为 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
});

我也想配置Connect的静态推销员以相同的方式表现(现在它默认为将静态文件提供给 something.com/js 或者 something.com/css 代替 something.com/myapp/js)

有帮助吗?

解决方案

目前不支持这一点,并且独自添加它并不容易。

整个路由物品都埋在服务器代码内部的深处,作为奖励,他们的自我途径没有曝光。

我挖掘了源头,还检查了最新版本的Express和Connect Middleware,但仍然没有对此类功能的支持,您应该在 连接 或者 表达 本身。

同时...

自己修补东西,这是一种快速简便的方法,只有一行代码更改。

~/.local/lib/node/.npm/express/1.0.0/package/lib/express/servers.js, , 搜索:

// Generate the route
this.routes[method](path, fn);

这应该在线 357, ,替换为:

// Generate the route
this.routes[method](((self.settings.base || '') + path), fn);

现在只添加设置:

app.set('base', '/myapp');

这与普通字符串的路径很好,对于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;
    }
}

我只用少数表达式对此进行了测试,因此这不是100%测试,但从理论上讲,它应该起作用。

更新2

提交了该补丁的问题:
https://github.com/visionmedia/express/issues/issue/478

其他提示

自4.0以来,快速路由器可以处理此操作

http://expressjs.com/en/api.html#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);

干杯!

我能够使用为路线的快速命名空间和以下Google组讨论静态资产讨论的解决方案来实现这一目标。该片段将像请求一样,将请求处理到/foo/javascripts/jquery.js。

app.use('/foo', express.static(__dirname + '/public'));

资源: https://groups.google.com/forum/#!/express-js/xlp6_dx6he0/6oty4hwfv-0j

还有可靠性问题。如果可靠性很重要,则常用解决方案是使用前端反向HTTP代理,例如Nginx或Haproxy。他们都使用单线程事件架构,因此非常可扩展。

然后,您可以为不同的子站点拥有不同的节点进程,如果一个站点失败(未透露异常,内存泄漏,程序员错误等等),则其余子站继续工作。

我一直在寻找此功能,但是API路由,而不是静态文件。我所做的是,当我初始化路由器时,我添加了安装路径。所以我的配置看起来像这样

//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的路由器将特定路径背后的相关功能分组在一起。这有很好的记录,并且已经被其他答案所涵盖。

但是,也可以将整个应用程序安装在特定路径上。例如,让我们假设我们的应用程序(我们要托管的应用程序 /myapp)看起来像这样的文件 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文件中,我们可以将整个应用程序安装在路径上 /myapp:

var express = require('express'),
    app = express(),
    myApp = require('./myapp').app;

app.use('/myapp', myApp);

app.listen(3000);

请注意,我们在这里创建了两个应用程序,一个应用程序安装在另一个应用程序。主应用程序可以根据需要在不同的路径上安装进一步的子应用程序。

代码在 myapp.js 完全独立于安装位置。它类似于 express-generator 在这方面。

有关子应用程序的一些文档可以在此处找到:

https://expressjs.com/en/4x/api.html#app.mountpath https://expressjs.com/en/4x/api.html#app.onmount

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top