Можно ли установить базовый URL для приложения NodeJS?


Я хочу иметь возможность размещать несколько приложений NodeJS в одном домене, не используя поддомены (например google.com/reader вместо того, чтобы images.google.com). проблема в том, что я всегда набираю первую часть url, например "/reader" в Express/NodeJS.

как я могу настроить Экспресс-приложение, чтобы базовый 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
});

Я также хотел бы настроить staticProvider подключения к вести себя так же (сейчас он по умолчанию обслуживает статические файлы something.com/js или something.com/css вместо something.com/myapp/js)

7   51  

7 ответов:

на данный момент это не поддерживается, и его нелегко добавить самостоятельно.

весь материал маршрутизации похоронен глубоко внутри кода сервера, и в качестве бонуса нет никакой экспозиции самих маршрутов.

я покопался в источнике, а также проверил последнюю версию 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');

это отлично работает с путями, которые являются простыми строками, для поддержки регулярных выражений вам придется взломать промежуточное программное обеспечение маршрутизатора вы сами, лучше подать вопрос в этом случае.

насколько статический провайдер идет, просто добавьте в /mypapp при настройке.

обновление

сделал его работать с регулярным выражением тоже:

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

Ура!

я смог добиться этого, используя комбинацию express-namespace для маршрутов и исправление из приведенного ниже группового обсуждения google для статических активов. Этот фрагмент будет обрабатывать запрос к /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

есть также вопросы надежности. Если надежность важна, общим решением является использование интерфейсного обратного HTTP-прокси, такого как nginx или HAProxy. Они оба используют однопоточную evented архитектуру и, таким образом, очень масштабируемы.

тогда у вас могут быть разные процессы узла для разных дочерних сайтов, и если один сайт терпит неудачу (неперехваченное исключение, утечка памяти, ошибка программиста, что угодно), остальные дочерние сайты продолжают работать.

Я искал эту функцию, но для маршрутов 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