nodejsアプリのベースURLを設定することは可能ですか?
質問
サブドメインを使用せずに、同じドメインの下で複数のnodeJSアプリをホストできるようにしたいと思います(images.google.comの代わりにgoogle.com/readerなど)。問題は、Express/nodejsのurl eg "/reader"の最初の部分を常に入力していることです。
ベース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
)
解決
現時点ではこれはサポートされておらず、自分で追加するのは簡単ではありません。
ルーティングのもの全体がサーバーコードの奥深くに埋もれており、ボーナスとして、ルートの露出はありません。
私はソースを掘り、ExpressとConnect Middlewareの最新バージョンもチェックアウトしましたが、そのような機能に対するサポートはまだありません。 接続 また 特急 自体。
その間...
自分でパッチを当ててください。コードが1行しか変更されていない迅速で簡単な方法があります。
の ~/.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
セットアップするとき。
アップデート
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
他のヒント
Expressルーターは、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-NamesSpaceモジュール(Dead Now)は、トリックを行うために使用されていました。
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-NamesSpaceの組み合わせと、静的資産の以下のGoogleグループディスカッションからの修正を使用してこれを達成することができました。このスニペットは、/javascripts/jquery.jsへのリクエストのように、/foo/javascripts/jquery.jsへのリクエストを扱います:
app.use('/foo', express.static(__dirname + '/public'));
ソース: https://groups.google.com/forum/#!msg/express-js/xlp6_dx6he0/6oty4hwfv-0j
信頼性の問題もあります。信頼性が重要である場合、一般的な解決策は、NginxやHaproxyなどのフロントエンドリバースHTTPプロキシを使用することです。どちらもシングルスレッドイベントアーキテクチャを使用しているため、非常にスケーラブルです。
その後、さまざまなサブサイトに対して異なるノードプロセスを作成できます。1つのサイトが失敗した場合(未装備の例外、メモリリーク、プログラマーエラーなど)、サブサイトの残りの部分は機能し続けます。
私はこの機能を探していましたが、静的ファイルではなく、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);
ここで2つのアプリケーションを作成したことに注意してください。1つはもう1つに取り付けられています。メインアプリケーションには、必要に応じてさまざまなパスにマウントされるサブアプリが追加される可能性があります。
コード myapp.js
マウントされた場所から完全に独立しています。それは、によって使用される構造に似ています express-generator
その点で。
サブアプリに関するいくつかのドキュメントは、こちらにあります:
https://expressjs.com/en/4x/api.html#app.mountpath https://expressjs.com/en/4x/api.html#app.onmount