Подтвердить что ты не робот

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

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

Как настроить приложение 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 staticProvider таким же образом (теперь он по умолчанию служит для обслуживания статических файлов на something.com/js или something.com/css вместо something.com/myapp/js)

4b9b3361

Ответ 1

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

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

Я вырыл источник, а также проверил последнюю версию Express и промежуточного программного обеспечения Connect, но до сих пор нет поддержки для таких функций, вы должны открыть проблему либо на Connect или Express.

В то же время...

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

В ~/.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

Ответ 2

Экспресс-маршрутизатор может справиться с этим с 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 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);

Предыдущий ответ (до экспресса 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
        });
});

Ответ 3

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

Ответ 4

Просто обновить поток, теперь с помощью 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);

Ура!

Ответ 5

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

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

Ответ 6

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

Ответ 7

Я знаю, что это очень старый вопрос, но 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