69

サブドメイン(images.google.comの代わりにgoogle.com/readerなど)を使用せずに、同じドメインで複数のNodeJSアプリをホストできるようにしたい。問題は、Express/NodeJSの「/reader」などのURLの最初の部分を常に入力していることです。

ベースURLがになるようにExpressアプリを設定するにはどうすればよい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

4

7 に答える 7

148

エクスプレスルーターは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
        });
});
于 2011-05-13T15:40:35.020 に答える
21

現時点ではこれはサポートされておらず、自分で追加するのは簡単ではありません。

ルーティング全体がサーバーコードの奥深くに埋め込まれており、ボーナスとして、ルーティング自体が公開されることはありません。

ソースを掘り下げて、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

于 2010-12-07T11:12:01.193 に答える
12

スレッドを更新するだけで、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);

乾杯!

于 2014-07-14T20:03:11.853 に答える
7

これは、ルートのエクスプレス名前空間と、静的アセットに関する以下の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

于 2012-09-18T21:32:44.320 に答える
4

これは非常に古い質問ですが、これらの回答のほとんどが投稿されてから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.mountpath https://expressjs.com/en/4x/api.html#app.onmount

于 2017-09-13T20:59:19.597 に答える
3

信頼性の問題もあります。信頼性が重要な場合、一般的な解決策は、nginxやHAProxyなどのフロントエンドリバースHTTPプロキシを使用することです。どちらもシングルスレッドのイベントアーキテクチャを使用しているため、非常にスケーラブルです。

次に、サブサイトごとに異なるノードプロセスを設定でき、1つのサイトに障害が発生した場合(キャッチされない例外、メモリリーク、プログラマーエラーなど)、残りのサブサイトは引き続き機能します。

于 2011-09-05T19:20:24.690 に答える
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」に注意してください

于 2013-04-19T13:10:44.593 に答える