Можно ли установить базовый URL для приложения NodeJS? - PullRequest
58 голосов
/ 07 декабря 2010

Я хочу иметь возможность размещать несколько приложений NodeJS в одном домене без использования поддоменов (например, google.com/reader вместо images.google.com). Проблема в том, что я всегда печатаю первую часть URL, например "/ читатель" в 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 так, чтобы он вел себя таким же образом (сейчас по умолчанию для статических файлов используется something.com/js или something.com/css вместо something.com/myapp/js)

Ответы [ 7 ]

127 голосов
/ 13 мая 2011

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

Предыдущий ответ (до экспресс 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
        });
});
16 голосов
/ 07 декабря 2010

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

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

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

Между тем ...

Попробуйте сами, вот быстрый и простой способ с одной строкой кодаизменено.

В ~/.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 вам придется самостоятельно взломать промежуточное ПО маршрутизатора, лучше подать проблему в этом случае.

Что касается статического провайдераs, просто добавьте /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

8 голосов
/ 15 июля 2014

Просто для обновления темы, теперь с 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);

Cheers!

7 голосов
/ 19 сентября 2012

Мне удалось добиться этого, используя комбинацию пространства экспресс-имен для маршрутов и исправления из приведенного ниже обсуждения группы Google для статических ресурсов. Этот фрагмент будет обрабатывать запрос к /foo/javascripts/jquery.js как запрос к /javascripts/jquery.js:

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

* Источник: 1005 * https://groups.google.com/forum/#!msg/express-js/xlP6_DX6he0/6OTY4hwfV-0J

3 голосов
/ 05 сентября 2011

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

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

2 голосов
/ 19 апреля 2013

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

1 голос
/ 13 сентября 2017

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...