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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4375554/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 13:45:46  来源:igfitidea点击:

Is it possible to set a base URL for NodeJS app?

node.jsconnectexpress

提问by David Tang

I want to be able to host multiple NodeJS apps under the same domain, without using sub-domains (like google.com/reader instead of images.google.com). The problem is that I'm always typing the first part of the url e.g. "/reader" in Express/NodeJS.

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

How can I set up an Express app so that the base URL is something.com/myapp?

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

So instead of:

所以而不是:

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

I can do:

我可以:

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

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

I'd also like to configure Connect's staticProvider to behave the same way (right now it defaults to serving static files to something.com/jsor something.com/cssinstead of something.com/myapp/js)

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

采纳答案by Ivo Wetzel

At the moment this is not supported, and it's not easy to add it on your own.

目前不支持,自己添加也不容易。

The whole routing stuff is buried deep inside the server code, and as a bonus there's no exposure of the routes them selfs.

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

I dug through the source and also checked out the latest version of Express and the Connect middleware, but there's still no support for such functionality, you should open a issue either on Connector Expressitself.

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

Meanwhile...

同时...

Patch the thing yourself, here's a quick and easy way with only one line of code changed.

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

In ~/.local/lib/node/.npm/express/1.0.0/package/lib/express/servers.js, search for:

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

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

This should be around line 357, replace that with:

这应该在 line 附近357,将其替换为:

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

Now just add the setting:

现在只需添加设置:

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

This works fine with paths that are plain strings, for RegEx support you will have to hack around in the router middleware yourself, better file an issue in that case.

这适用于纯字符串的路径,对于 RegEx 支持,您必须自己在路由器中间件中进行修改,在这种情况下最好提交问题。

As far as the static provider goes, just add in /mypappwhen setting it up.

至于静态提供者,只需在/mypapp设置时添加即可。

Update

更新

Made it work with RegExp too:

也让它与 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;
    }
}

I only tested this with a handful of expressions, so this isn't 100% tested but in theory it should work.

我只用少数表达式测试了这个,所以这不是 100% 测试,但理论上它应该可以工作。

Update 2

更新 2

Filed an issue with the patch:
https://github.com/visionmedia/express/issues/issue/478

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

回答by Remi Mélisson

The express router can handle this since 4.0

从 4.0 开始,express 路由器就可以处理这个问题

http://expressjs.com/en/api.html#router

http://expressjs.com/en/api.html#router

http://bulkan-evcimen.com/using_express_router_instead_of_express_namespace.html

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);


Previous answer (before express 4.0) :

上一个答案(在 express 4.0 之前):

The express-namespace module (dead now) used to do the trick :

express-namespace 模块(现在已经死了)用来做这个伎俩:

https://github.com/visionmedia/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
        });
});

回答by danilodeveloper

Just to update the thread, now with Express.jsv4you can do it without using express-namespace:

只是为了更新线程,现在使用Express.jsv4,您可以在不使用的情况下进行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);

Cheers!

干杯!

回答by Ben Zittlau

I was able to achieve this using a combination of express-namespace for the routes and a fix from the below google group discussion for the static assets. This snippet will treat a request to /foo/javascripts/jquery.js like a request to /javascripts/jquery.js:

我能够使用路由的 express-namespace 和下面谷歌小组讨论中的静态资产的修复来实现这一点。此代码段将对 /foo/javascripts/jquery.js 的请求视为对 /javascripts/jquery.js 的请求:

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

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

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

回答by Xerri

I was looking for this feature but for API routes, not for static files. What I did was that when I initialized the router, I added the mount path. So my configuration looks like this

我正在寻找此功能,但用于 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, {});
    });
});

Notice the '/api' when calling the router

调用路由器时注意“/api”

回答by nponeccop

There are also reliability issues. If reliability is important, a common solution is to use a front-end reverse HTTP proxy such as nginx or HAProxy. They both use single-thread evented architecture and are thus very scalable.

还有可靠性问题。如果可靠性很重要,一个常见的解决方案是使用前端反向 HTTP 代理,例如 nginx 或 HAProxy。它们都使用单线程事件架构,因此具有很高的可扩展性。

Then you can have different node processes for different subsites, and if one site fails (uncaught exception, memory leak, programmer error, whatever) the rest of sub-sites continue to work.

然后你可以为不同的子站点使用不同的节点进程,如果一个站点失败(未捕获的异常、内存泄漏、程序员错误等等),其余的子站点会继续工作。

回答by skirtle

I know this is a very old question but Express has changed a lot since most these answers were posted so I thought I'd share my approach.

我知道这是一个非常古老的问题,但 Express 已经发生了很大变化,因为大多数这些答案都已发布,所以我想我会分享我的方法。

You can, of course, use Routers with Express 4 to group together related functionality behind a particular path. This is well documented and has already been covered by other answers.

当然,您可以使用路由器与 Express 4 将特定路径后面的相关功能组合在一起。这是有据可查的,并且已经被其他答案所涵盖。

However, it is also possible to mount an entire application at a particular path. As an example, let's assume our application (the one we want to host at /myapp) looks like this, in a file called myapp.js:

但是,也可以在特定路径上安装整个应用程序。例如,让我们假设我们的应用程序(我们想要托管的应用程序/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;

In our main js file we could then mount this whole application at the path /myapp:

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

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

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

app.listen(3000);

Note that we've created two applications here, one mounted on the other. The main application could have further sub-apps mounted at different paths as required.

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

The code in myapp.jsis completely independent of where it was mounted. It's similar to the structure used by the express-generatorin that regard.

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

Some documentation about sub-apps can be found here:

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

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

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