是否可以为NodeJS应用程序设置基本URL?

Dav*_*ang 59 connect node.js express

我希望能够在同一个域下托管多个NodeJS应用,而无需使用子域(例如google.com/reader而不是images.google.com).问题是我总是在Express/NodeJS中输入网址的第一部分,例如"/ reader".

如何设置Express应用程序以使基本URL成为something.com/myapp

所以代替:

app.get("/myapp", function (req, res) {
   // can be accessed from something.com/myapp
});
Run Code Online (Sandbox Code Playgroud)

我可以:

// Some set-up
app.base = "/myapp"

app.get("/", function (req, res) {
   // can still be accessed from something.com/myapp
});
Run Code Online (Sandbox Code Playgroud)

我还想将Connect的staticProvider配置为以相同的方式运行(现在它默认为提供静态文件something.com/jssomething.com/css代替something.com/myapp/js)

Rem*_*son 131

Express 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);
Run Code Online (Sandbox Code Playgroud)

上一个答案(快递4.0之前):

快速命名空间模块(现在已经死了)用来做诀窍:

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
        });
});
Run Code Online (Sandbox Code Playgroud)

  • 来自Google的人员请注意:即使没有标记,这也是正确的答案.通常最好避免猴子修补一个维护良好的库,如果可能的话. (18认同)
  • 进一步说明 - 项目似乎已经死了https://github.com/expressjs/express-namespace/issues/44使用快递4中的路由器http://bulkan-evcimen.com/using_express_router_instead_of_express_namespace.html (4认同)

Ivo*_*zel 17

目前不支持此功能,并且您自己添加它并不容易.

整个路由的东西都埋藏在服务器代码的深处,作为奖励,他们自己的路线没有暴露.

我挖掘了源代码并检查了最新版本的Express和Connect中间件,但仍然不支持此类功能,您应该在ConnectExpress本身上打开一个问题.

与此同时...

自己修补这个问题,这里只需更改一行代码即可快速简便地完成.

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

// Generate the route
this.routes[method](path, fn);
Run Code Online (Sandbox Code Playgroud)

这应该是在线357,用以下代替:

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

现在只需添加设置:

app.set('base', '/myapp');
Run Code Online (Sandbox Code Playgroud)

这适用于普通字符串的路径,对于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;
    }
}
Run Code Online (Sandbox Code Playgroud)

我只用一些表达式对它进行了测试,所以这不是100%经过测试,但理论上它应该可行.

更新2

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

  • 覆盖第三方库并不明智,因为每次更新到新版本时,您还需要向其中重新添加代码。 (2认同)

dan*_*per 10

只是为了更新线程,现在用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);
Run Code Online (Sandbox Code Playgroud)

干杯!


Ben*_*lau 7

我能够使用针对路线的快速命名空间和针对静态资产的以下谷歌小组讨论的修复来实现此目的.该片段将处理对/foo/javascripts/jquery.js的请求,如对/javascripts/jquery.js的请求:

app.use('/foo', express.static(__dirname + '/public'));
Run Code Online (Sandbox Code Playgroud)

来源: https ://groups.google.com/forum/#! msg/ express- js/ xlP6_DX6he0/6OTY4hwfV-0J

  • 这必须是答案,而不是破解核心. (4认同)

ski*_*tle 5

我知道这是一个非常古老的问题,但自从大多数答案发布以来,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;
Run Code Online (Sandbox Code Playgroud)

在我们的主 js 文件中,我们可以将整个应用程序挂载到以下路径/myapp

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

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

app.listen(3000);
Run Code Online (Sandbox Code Playgroud)

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

中的代码myapp.js完全独立于其安装位置。它与在这方面使用的结构类似express-generator

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

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