Nœud.js / Express.js - Comment fonctionne l'application.routeur de travail?

avant de poser des questions sur app.router je pense que je devrais expliquer au moins ce que je pense qui se passe en travaillant avec middleware. Pour utiliser middleware, la fonction à utiliser est app.use() . Quand le middleware est exécuté, il appellera le middleware suivant en utilisant next() ou le fera si pas plus middleware obtenir appelé. Cela signifie que l'ordre dans lequel je place mes middleware appels est important, parce que certains middleware dépend d'autres middleware, et certains middleware près de la la fin pourrait ne pas être appelée.

Aujourd'hui, je travaillais sur mon application et mon serveur fonctionnait en arrière-plan. Je voulais faire quelques modifications et actualiser ma page et voir les changements immédiatement. Plus précisément, j'apportais des changements à mon agencement. Je n'ai pas pu le faire fonctionner alors j'ai cherché Stack Overflow pour la réponse et j'ai trouvé cette question . Il dit de s'assurer que express.static() est en dessous de require('stylus') . Mais quand je regardais cette opération code, j'ai vu qu'il avait son app.router appel à la fin de son middleware appels, et j'ai essayé de comprendre pourquoi.

quand j'ai fait mon Express.js application (version 3.0.0rc4), j'ai utilisé la commande express app --sessions --css stylus et dans mon application.fichier js le code a été configuré avec mes appels app.router au-dessus des appels express.static() et require('stylus') . Donc, il semble que, si elle vient déjà mis en place cette façon, alors il devrait rester de cette façon.

après réorganisation mon code pour que je puisse voir mon stylet change, il ressemble à ceci:

app.configure(function(){
  //app.set() calls
  //app.use() calls
  //...
  app.use(app.router);
  app.use(require('stylus').middleware(__dirname + '/public'));
  app.use(express.static(__dirname + '/public', {maxAge: 31557600000}));
});

app.get('/', routes.index);

app.get('/test', function(req, res){
  res.send('Test');
});

j'ai Donc décidé que la première étape serait de savoir pourquoi il est important d'avoir encore app.router dans mon code. J'ai donc commenté, commencé mon application et navigué à / . Il a affiché ma page d'index très bien. Hmm, peut-être que ça a marché parce que j'exportais le routage à partir de mon fichier de routes (routes.index.) Donc ensuite j'ai navigué sur /test et il a affiché le Test sur l'écran. Haha, OK, je n'ai aucune idée de ce que fait app.router . Que ce soit inclus ou non dans mon code, MON routage est parfait. Donc, je suis définitivement en manque de quelque chose.

Alors Voici Ma Question:

est-ce que quelqu'un pourrait s'il vous plaît expliquer ce que app.router fait, l'importance de celui-ci, et où je devrais le placer dans mes appels middleware? Ce serait aussi bien si j'avais une brève explication sur express.static() . Pour autant que je sache, express.static() est un cache de mes informations, et si l'application ne peut pas trouver la page demandée, il va vérifier le cache pour voir si elle existe.

289
demandé sur Community 2012-10-02 21:53:47

3 réponses

Note: ceci décrit comment Express a travaillé dans les versions 2 et 3. Voir la fin de ce post pour plus d'informations sur Express 4.


static sert simplement des dossiers ( statique ressources) du disque. Donnez-vous un chemin (parfois appelé le point de montage), et il sert les fichiers dans ce dossier.

par exemple, express.static('/var/www') servirait les fichiers dossier. Ainsi, une requête à votre serveur de noeuds pour http://server/file.html servirait /var/www/file.html .

router est le code qui parcourt vos itinéraires. Quand vous faites app.get('/user', function(req, res) { ... }); , c'est le router qui invoque en fait la fonction callback pour traiter la requête.

l'ordre dans lequel vous passez les choses à app.use détermine l'ordre dans lequel chaque middleware a la possibilité de traiter une demande. Par exemple, si vous avez un fichier nommé test.html dans votre dossier statique et une route:

app.get('/test.html', function(req, res) {
    res.send('Hello from route handler');
});

lequel est envoyé à un client demandant http://server/test.html ? Quel que soit l'middleware donné en premier lieu à use .

si vous faites cela:

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

puis le fichier sur disque est servi.

Si vous le faites dans l'autre sens,

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

puis le gestionnaire de route obtient la demande, et " bonjour de la route handler" est envoyé au navigateur.

habituellement, vous voulez mettre le routeur au-dessus de le middleware statique de sorte qu'un fichier nommé accidentellement ne peut pas outrepasser une de vos routes.

notez que si vous ne le faites pas explicitement use le router , il est implicitement ajouté par Express au point que vous définissez une route (c'est pourquoi vos routes ont toujours fonctionné même si vous avez commenté app.use(app.router) ).


un commentateur a soulevé un autre point sur l'ordre de static et router que je n'avais pas abordé: l'impact sur la performance globale de votre application.

une autre raison pour use router au-dessus de static est d'optimiser les performances. Si vous mettez static en premier, alors vous frapperez le disque dur sur chaque demande pour voir si oui ou non un fichier existe. Dans un quick test , j'ai trouvé que ce overhead s'élevait à ~1ms sur un serveur non chargé. (Ce nombre est très probablement plus élevé sous charge, où les demandes seront en concurrence pour l'accès disque.)

avec router tout d'abord, une requête correspondant à une route n'a jamais à atteindre le disque, économisant des millisecondes précieuses.

bien sûr, il y a des moyens d'atténuer les frais généraux de static .

la meilleure option est de mettre tous de vos ressources statiques sous un dossier spécifique. (I.e. /static ) vous pouvez ensuite monter static sur ce chemin de sorte qu'il ne court que lorsque le chemin commence par /static :

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

dans cette situation, vous mettez ça au-dessus de router . Cela évite de traiter d'autres middlewares/le routeur si un fichier est présent, mais pour être honnête, je doute que vous gagnerez autant.

vous pouvez également utiliser staticCache , qui cache les ressources statiques en mémoire de sorte que vous n'avez pas à frapper le disque pour les fichiers demandés couramment. ( Avertissement: staticCache sera apparemment être supprimé dans l'avenir.)

cependant, je ne pense pas que staticCache cache des réponses négatives (quand un fichier n'existe pas), donc cela n'aide pas si vous avez mis staticCache au-dessus de router sans le monter sur un chemin.

comme pour tous questions sur la performance, mesurer et comparer votre application réelle (sous charge) pour voir où les goulots d'étranglement sont vraiment.


Express 4

Express 4.0 supprime app.router . Tous les middlewares ( app.use ) et les routes ( app.get et al) sont maintenant traités dans l'ordre précis dans lequel ils sont ajoutés.

En d'autres termes:

toutes les méthodes de routage seront ajoutées dans l'ordre où elles apparaissent. Vous devez pas faire app.use(app.router) . Cela élimine le problème le plus courant avec Express.

En d'autres termes, le mélange app.use() et app[VERB]() travaillera exactement dans l'ordre dans lequel ils sont appelés.

app.get('/', home);
app.use('/public', require('st')(process.cwd()));
app.get('/users', users.list);
app.post('/users', users.create);

plus d'informations à propos modifications dans Express 4.

326
répondu josh3736 2017-05-23 10:31:06

routage signifie déterminer comment une application répond à une demande d'un client à un endpoint particulier, qui est une URI (ou un chemin) et une méthode de requête HTTP spécifique (GET, POST, et ainsi de suite). Chaque route peut avoir une ou plusieurs fonctions handler, qui sont exécutées lorsque la route est appariée.

dans Express 4.0 Router, nous avons plus de flexibilité que jamais dans la définition de nos itinéraires.

express.Routeur() est l'utilisation plusieurs fois pour définir des groupes de routes.

route utilisée comme middleware pour traiter les requêtes.

itinéraire utilisé en tant que middleware pour valider les paramètres à l'aide ".param ()".

app.route() utilisée comme raccourci vers le routeur pour définir des requêtes multiples sur une route

quand nous utilisons app.route(), nous attachons notre app avec ce routeur.

var express = require('express'); //used as middleware
var app = express(); //instance of express.
app.use(app.router);
app.use(express.static(__dirname + '/public')); //All Static like [css,js,images] files are coming from public folder
app.set('views',__dirname + '/views'); //To set Views
app.set('view engine', 'ejs'); //sets View-Engine as ejs
app.engine('html', require('ejs').renderFile); //actually rendering HTML files through EJS. 
app.get('/', function (req, res) {
  res.render('index');  
})
app.get('/test', function (req, res) {
  res.send('test')
})
2
répondu Parth Raval 2016-11-04 17:21:17

dans express Version 4, nous pouvons facilement définir les routes de la manière suivante:

server.js:

const express = require('express');
const app = express();
const route = require('./route');

app.use('/route', route);
// here we pass in the imported route object

app.listen(3000, () => console.log('Example app listening on port 3000!'));

route.js:

const express = require('express');
const router = express.Router();

router.get('/specialRoute', function (req, res, next) {
     // route is now http://localhost:3000/route/specialRoute
});

router.get('/', function (req, res, next) {
    // route is now http://localhost:3000/route
});

module.exports = router;

Dans server.js nous avons importé le routeur objet de la route.js fichier et de l'appliquer de la manière suivante dans server.js :

app.use('/route', route);

maintenant toutes les routes en le route.js ont L'URL de base suivante:

http://localhost:3000/route

pourquoi cette approche:

Le principal avantage de cette approche est que maintenant notre application est plus modulaire . Tous les gestionnaires de routes pour une certaine route peuvent maintenant être placés dans des fichiers différents, ce qui rend tout plus maintenable et plus facile à trouver.

0
répondu Willem van der Veen 2018-09-12 07:54:21