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