Diferencia entre app.all ('*') y app.use ('/')

121

¿Existe una diferencia útil entre app.all('*', ... )y app.use('/', ...)en Node.JS Express?

Ostergaard
fuente

Respuestas:

119

En la mayoría de los casos, funcionarían de manera equivalente. La mayor diferencia es el orden en el que se aplicaría el middleware:

  • app.all() se conecta al enrutador de la aplicación, por lo que se usa siempre que se alcanza el middleware app.router (que maneja todas las rutas del método ... GET, POST, etc.).

AVISO: app.router ha quedado obsoleto en Express 4.x

  • app.use()se adjunta a la pila principal de middleware de la aplicación, por lo que se usa en el orden especificado por el middleware. por ejemplo, si lo pone primero, será lo primero que se ejecute. Si lo coloca en último lugar (después del enrutador), generalmente no se ejecutará en absoluto.

Por lo general, si desea hacer algo globalmente en todas las rutas, app.use () es la mejor opción. Además, tiene menos posibilidades de errores en el futuro, ya que express 0.4 probablemente eliminará el enrutador implícito (lo que significa que la posición del enrutador en el middleware será más importante de lo que es ahora, ya que técnicamente ni siquiera tiene que usarlo ahora mismo).

hunterloftis
fuente
15
¿Esto todavía se aplica después de Express 4.x? app.router fue eliminado.
ruffrey
1
Puede usar next("route")con app.all, pero no con app.use.
Jozef Mikušinec
@JozefMikusinec La documentación parece sugerir lo contrario ... expressjs.com/en/guide/writing-middleware.html
musicin3d
Su enlace no menciona la siguiente ('ruta'), pero miré la API, tiene razón.
Jozef Mikušinec
2
@ musicin3d Investigué más y encontré este problema de GitHub , que confirma que "next () y next ('route') no tienen ninguna diferencia con app.use" (cita). Deberían cambiar los documentos.
Jozef Mikušinec
87

app.use solo acepta una función de devolución de llamada y está destinada a Middleware. El middleware generalmente no maneja solicitudes y respuestas (técnicamente pueden), solo procesan los datos de entrada y los entregan al siguiente controlador en la cola.

app.use([path], function)

app.all acepta múltiples devoluciones de llamada y está diseñado para enrutamiento. con múltiples devoluciones de llamada, puede filtrar solicitudes y enviar respuestas. Se explica en Filtros en express.js

app.all(path, [callback...], callback)

app.use solo ve si la URL comienza con la ruta especificada

app.use( "/product" , mymiddleware);
// will match /product
// will match /product/cool
// will match /product/foo

app.all coincidirá con la ruta completa

app.all( "/product" , handler);
// will match /product
// won't match /product/cool   <-- important
// won't match /product/foo    <-- important

app.all( "/product/*" , handler);
// won't match /product        <-- Important
// will match /product/
// will match /product/cool
// will match /product/foo
Palani
fuente
17
Al menos en v4, app.use toma una o más funciones de middleware, no "solo una".
Jess Austin
2
app.use solo ve si la URL comienza con la ruta especificada; app.all coincidirá con la ruta completa. esta es la principal diferencia.
meizilp
@frogcjn no, no debería, ya que ignora el * y / en mi pregunta.
ostergaard
15
  • uso de la aplicación:

    1. inyecte middlware en su controlador frontal configurando, por ejemplo: encabezado, cookies, sesiones, etc.
    2. debe escribirse antes de la aplicación [http_method]; de lo contrario, no se ejecutará.
    3. varias llamadas se procesan en el orden de escritura
  • espantar:

    1. (como la aplicación [http_method]) se utiliza para configurar los controladores de rutas
    2. "todos" significa que se aplica a todos los métodos http.
    3. varias llamadas se procesan en el orden de escritura

Mira este ejemplo de código de expressJs:

var express = require('express');
var app = express();

app.use(function frontControllerMiddlewareExecuted(req, res, next){
  console.log('(1) this frontControllerMiddlewareExecuted is executed');
  next();
});

app.all('*', function(req, res, next){
  console.log('(2) route middleware for all method and path pattern "*", executed first and can do stuff before going next');
  next();
});

app.all('/hello', function(req, res, next){
  console.log('(3) route middleware for all method and path pattern "/hello", executed second and can do stuff before going next');
  next();
});

app.use(function frontControllerMiddlewareNotExecuted(req, res, next){
  console.log('(4) this frontControllerMiddlewareNotExecuted is not executed');
  next();
});

app.get('/hello', function(req, res){
  console.log('(5) route middleware for method GET and path patter "/hello", executed last and I do my stuff sending response');
  res.send('Hello World');
});

app.listen(80);

Aquí está el registro al acceder a la ruta '/ hola':

(1) this frontControllerMiddlewareExecuted is executed
(2) route middleware for all method and path pattern "*", executed first and can do stuff before going next
(3) route middleware for all method and path pattern "/hello", executed second and can do stuff before going next
(5) route middleware for method GET and path patter "/hello", executed last and I do my stuff sending response
daemon1981
fuente
6
Después de ejecutar este ejemplo textualmente en Express 4.x, en realidad ejecuta los 5 en orden. Es probable que esto se deba a cambios en express en los casi 3 años desde que se escribió esto, pero pensé en agregar esto para mayor claridad.
Nathan Wiebe
11

Con app.use(), la ruta de "montaje" se elimina y no es visible para la función de middleware:

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

Las funciones de middleware montadas ( express.static) no se invocan a menos que req.urlcontenga este prefijo ( /static), en cuyo momento se elimina cuando se invoca la función.

Con app.all(), no hay ese comportamiento.

mejor9
fuente
La pregunta pregunta explícitamente sobre app.use ('/', ...) únicamente.
ostergaard
¡Esta es la respuesta correcta a la pregunta que todavía es cierta en 2018! También se puede montar un middleware con all () ... la única diferencia es que la ruta de montaje se elimina al ejecutar el middleware.
Xatian
4

Sí, app.all()se llama cuando se solicita un URI en particular con cualquier tipo de método de solicitud (POST, GET, PUT o DELETE)

Por otro lado, app.use()se usa para cualquier middleware que pueda tener y se monta en un prefijo de ruta, y se llamará cada vez que se solicite un URI en esa ruta.

Aquí está la documentación para app.all y app.use .

Gurpreet Singh
fuente
gracias, pero creo que te perdiste el comodín app.all y app.use root path que los hace prácticamente lo mismo, ¿no? Excepto que app.all puede aceptar una variedad de devoluciones de llamada y app.use solo puede tomar una, ¿verdad?
ostergaard
1

Dos diferencias todas las respuestas anteriores no mencionan.

El primero: app.allacepta una expresión regular como parámetro de ruta. app.useNO acepta expresiones regulares.

El segundo: app.all(path,handler)o app[method](path,handler), el controlador pathdebe ser el mismo para todos path . Es decir, la ruta de la aplicación [método] está completa.

app.use(path,hanlder), si la ruta del uso está completa, la ruta del manejador debe ser '/'. Si la ruta del uso es el comienzo de la ruta completa, la ruta del manejador debe ser el resto de la ruta completa.

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

  //users.js:  the handler will be called when matchs `/user/` path
      router.get('/', function(req, res, next) {
      res.send('respond with a resource');
    });
  // others.js: the handler will be called when matchs `/users/users` path
      router.get('/users', function(req, res, next) {
      res.send('respond with a resource');
    });

app.all('/users', users);

//others.js: the handler wil be called when matchs `/`path
router.get('/', function(req, res, next) {
     res.send('respond with a resource');
});
//users.js: the handler will be called when matchs `/users` path
router.get('/users', function(req, res, next) {
    res.send('respond with a resource');
 });
JackChouMine
fuente
0

Hay dos diferencias principales:

1. coincidencia de patrones (respuesta dada por Palani)
2. next(route)no funcionará dentro del cuerpo de la función del middleware cargado con app.use. Esto se indica en el enlace de los documentos:

NOTE: next('route') will work only in middleware functions that were loaded by using the app.METHOD() or router.METHOD() functions.

Enlace: http://expressjs.com/en/guide/using-middleware.html

El efecto de trabajo de next('route')se puede ver en el siguiente ejemplo:

app.get('/',
(req,res,next)=>{console.log("1");
next(route); //The code here skips ALL the following middlewares
}
(req,res,next)=>{next();}, //skipped
(req,res,next)=>{next();}  //skipped
);

//Not skipped
app.get('/',function(req,res,next){console.log("2");next();});
Ng Ju Ping
fuente