Domanda

Voglio essere in grado di ospitare più applicazioni NodeJS sotto lo stesso dominio, senza l'utilizzo di sottodomini (come google.com/reader invece di images.google.com). Il problema è che sto sempre scrivendo la prima parte dell'URL per esempio "/ Lettore" in rapido / NodeJS.

Come posso creare un app Express in modo che l'URL di base è something.com/myapp?

Così, invece di:

app.get("/myapp", function (req, res) {
   // can be accessed from something.com/myapp
});

che posso fare:

// Some set-up
app.base = "/myapp"

app.get("/", function (req, res) {
   // can still be accessed from something.com/myapp
});

Mi piacerebbe anche a staticProvider di configurazione di collegamento a comportarsi nello stesso modo (in questo momento il default a servire i file statici per something.com/js o something.com/css invece di something.com/myapp/js)

È stato utile?

Soluzione

Al momento questo non è supportato, e non è facile aggiungere da soli.

La roba di routing intera è sepolto in profondità all'interno del codice del server, e come bonus non c'è alcuna esposizione dei percorsi loro self.

I scavato attraverso la sorgente e anche controllato l'ultima versione di Express e il middleware Connect, ma non c'è ancora alcun supporto per tale funzionalità, si dovrebbe aprire una questione sia su Connetti o espresso in sé .

Nel frattempo ...

Patch la cosa da soli, ecco un modo semplice e veloce con una sola riga di codice modificato.

In ~/.local/lib/node/.npm/express/1.0.0/package/lib/express/servers.js, cercare:

// Generate the route
this.routes[method](path, fn);

Questo dovrebbe essere di circa 357 riga, sostituire quello con:

// Generate the route
this.routes[method](((self.settings.base || '') + path), fn);

Ora basta aggiungere l'impostazione:

app.set('base', '/myapp');

Questo funziona bene con percorsi che sono stringhe semplici, per il supporto RegEx si dovrà incidere in giro per il router middleware da soli, meglio file di un problema in questo caso.

Per quanto riguarda il fornitore statica va, basta aggiungere in /mypapp quando la sua creazione.

Aggiorna

ha reso il lavoro con RegExp troppo:

// 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;
    }
}

Ho testato solo questo con una manciata di espressioni, quindi questo non è 100% provato ma in teoria dovrebbe funzionare.

Aggiorna 2

Archiviato un problema con la patch:
https://github.com/visionmedia/express/issues/issue/478

Altri suggerimenti

Il router espresso in grado di gestire questo dato 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);

Risposta precedente (prima di Express 4.0):

Il modulo Express-namespace (morto) usato per fare il trucco:

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
        });
});

Proprio per aggiornare il filo, ora con Express.js v4 è possibile farlo senza usare 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!

Sono stato in grado di raggiungere questo obiettivo utilizzando una combinazione di Express-namespace per le rotte e una correzione dalla discussione di gruppo sotto google per le attività statiche. Questo frammento tratterà una richiesta di /foo/javascripts/jquery.js come una richiesta di /javascripts/jquery.js:

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

Fonte: https://groups.google.com/forum/# ! msg / esprimere-js / xlP6_DX6he0 / 6OTY4hwfV-0J

Ci sono anche problemi di affidabilità. Se l'affidabilità è importante, una soluzione comune è quella di utilizzare un front-end inverso HTTP proxy come nginx o HAProxy. Entrambi uso singolo filo evented architettura e sono quindi molto scalabile.

Poi si può avere diversi processi di nodo per i diversi siti secondari, e se un sito non riesce (eccezioni non rilevate, perdita di memoria, errore di programmazione, a prescindere) il resto dei siti secondari continuano a lavorare.

Ero alla ricerca di questa caratteristica, ma per le rotte API, non per i file statici. Quello che ho fatto è che quando ho inizializzato il router, ho aggiunto il percorso di montaggio. Quindi, il mio aspetto di configurazione come questo

//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, {});
    });
});

Si noti il ??'/ api' quando si chiama il router

So che questa è una domanda molto vecchio ma espresso è cambiato molto da quando la maggior parte queste risposte sono state inviate così ho pensato di condividere il mio approccio.

È possibile, naturalmente, utilizzare router con Express 4 per raggruppare funzionalità correlate alle spalle un particolare percorso. Questo è ben documentato ed è già stato coperto da altre risposte.

Tuttavia, è anche possibile montare un'intera applicazione in un determinato percorso. Per fare un esempio, supponiamo che la nostra applicazione (quella che vogliamo ospite a /myapp) assomiglia a questo, in un file chiamato 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;

Nel file delle nostre principali js potremmo poi montare tutta questa applicazione al /myapp percorso:

var express = require('express'),
    app = express(),
    myApp = require('./myapp').app;

app.use('/myapp', myApp);

app.listen(3000);

Si noti che abbiamo creato due applicazioni qui, uno montato sull'altro. L'applicazione principale potrebbe avere ulteriori sotto-applicazioni montati percorsi diversi come richiesto.

Il codice in myapp.js è completamente indipendente dal luogo in cui è stato montato. E 'simile alla struttura utilizzata dal express-generator al riguardo.

Alcuni documentazione su sub-apps può essere trovato qui:

https://expressjs.com/en/4x/api.html # app.mountpath https://expressjs.com/en/4x/api.html#app. onmount

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top