サブドメイン(images.google.comの代わりにgoogle.com/readerなど)を使用せずに、同じドメインで複数のNodeJSアプリをホストできるようにします。問題は、URLの最初の部分を常に入力していることです。 Express/NodeJSの「/ reader」。
ベースURLがsomething.com/myapp
になるようにExpressアプリを設定するにはどうすればよいですか?
代わりに:
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ミドルウェアの最新バージョンもチェックアウトしましたが、そのような機能はまだサポートされていません。 Connect または Express 自体。
その間...
自分でパッチを適用してください。ここでは、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');
これは、プレーン文字列のパスで正常に機能します。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
エクスプレスルーターは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以前):
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);
乾杯!
ルートのエクスプレス名前空間と、以下の静的アセットの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
信頼性の問題もあります。信頼性が重要な場合、一般的なソリューションは、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つのアプリケーションを作成し、一方が他方にマウントされていることに注意してください。メインアプリケーションには、必要に応じて別のパスに追加のサブアプリをマウントできます。
myapp.js
のコードは、マウントされた場所とは完全に独立しています。その点でexpress-generator
によって使用される構造に似ています。
サブアプリに関するドキュメントはこちらにあります。
https://expressjs.com/en/4x/api.html#app.mountpathhttps://expressjs.com/en/4x/api.html#app.onmount