Perbedaan antara app.all ('*') dan app.use ('/')

121

Apakah ada perbedaan yang berguna antara app.all('*', ... )dan app.use('/', ...)di Node.JS Express?

ostergaard
sumber

Jawaban:

119

Dalam kebanyakan kasus, mereka akan bekerja dengan cara yang sama. Perbedaan terbesar adalah urutan penerapan middleware:

  • app.all() menempel ke router aplikasi, sehingga digunakan setiap kali app.router middleware tercapai (yang menangani semua rute metode ... GET, POST, dll).

PEMBERITAHUAN: app.router sudah tidak digunakan lagi di express 4.x.

  • app.use()menempel pada tumpukan middleware utama aplikasi, sehingga digunakan dalam urutan yang ditentukan oleh middleware. misalnya, jika Anda mengutamakannya, ini akan menjadi hal pertama yang dijalankan. Jika Anda meletakkannya terakhir, (setelah router), biasanya tidak akan berjalan sama sekali.

Biasanya, jika Anda ingin melakukan sesuatu secara global ke semua rute, app.use () adalah opsi yang lebih baik. Selain itu, kemungkinan bug di masa mendatang lebih kecil, karena express 0.4 mungkin akan menjatuhkan router implisit (artinya, posisi router di middleware akan lebih penting daripada sekarang, karena secara teknis Anda bahkan tidak perlu menggunakannya. sekarang juga).

hunterloftis
sumber
15
Apakah ini masih berlaku setelah Express 4.x? app.router telah dihapus.
ruffrey
1
Anda bisa menggunakan next("route")dengan app.all, tapi tidak dengan app.use.
Jozef Mikušinec
@JozefMikusinec Dokumentasi tampaknya menyarankan sebaliknya ... expressjs.com/en/guide/writing-middleware.html
musicin3d
Tautan Anda tidak menyebutkan next ('rute'), tetapi saya melihat API, Anda benar.
Jozef Mikušinec
2
@ musicin3d Saya meneliti lebih lanjut dan menemukan masalah GitHub ini , yang menegaskan bahwa "next () dan next ('route') tidak ada bedanya dengan app.use" (kutipan). Mereka harus mengubah dokumen.
Jozef Mikušinec
87

app.use hanya membutuhkan satu fungsi panggilan balik dan itu dimaksudkan untuk Middleware. Middleware biasanya tidak menangani permintaan dan respons, (secara teknis mereka bisa) mereka hanya memproses data masukan, dan menyerahkannya ke penangan berikutnya dalam antrian.

app.use([path], function)

app.all menerima banyak panggilan balik, dan dimaksudkan untuk perutean. dengan beberapa panggilan balik, Anda dapat memfilter permintaan dan mengirim tanggapan. Ini dijelaskan dalam Filter di express.js

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

app.use hanya melihat apakah url dimulai dengan jalur yang ditentukan

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

app.all akan mencocokkan jalur lengkap

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
sumber
17
Setidaknya di v4, app.use menggunakan satu atau lebih fungsi middleware, bukan "hanya satu".
Jess Austin
2
app.use hanya melihat apakah url dimulai dengan jalur yang ditentukan; app.all akan cocok dengan jalur lengkap. inilah perbedaan utama.
meizilp
@frogcjn tidak seharusnya tidak karena mengabaikan * dan / dalam pertanyaan saya.
ostergaard
15
  • app.use:

    1. menyuntikkan middlware ke pengontrol depan Anda yang mengonfigurasi misalnya: header, cookie, sesi, dll.
    2. harus ditulis sebelum aplikasi [http_method] jika tidak maka tidak akan dijalankan.
    3. beberapa panggilan diproses dalam urutan penulisan
  • menggemparkan:

    1. (seperti app [http_method]) digunakan untuk mengkonfigurasi pengontrol rute
    2. "semua" berarti ini berlaku di semua metode http.
    3. beberapa panggilan diproses dalam urutan penulisan

Lihat contoh kode expressJs ini:

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

Berikut adalah log saat mengakses rute '/ hello':

(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
sumber
6
Setelah menjalankan contoh ini secara verbatim pada express 4.x, ini sebenarnya menjalankan semua 5 secara berurutan. Ini mungkin karena perubahan ekspres dalam hampir 3 tahun sejak ini ditulis, tetapi saya hanya berpikir saya akan menambahkan ini untuk kejelasan.
Nathan Wiebe
11

Dengan app.use(), jalur "mount" dihilangkan dan tidak terlihat oleh fungsi middleware:

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

Fungsi middleware yang terpasang ( express.static) tidak dipanggil kecuali jika req.urlberisi awalan ini ( /static), yang pada titik itu akan dilucuti ketika fungsi dipanggil.

Dengan app.all(), tidak ada perilaku itu.

lebih baik9
sumber
Pertanyaannya secara eksplisit menanyakan tentang app.use ('/', ...) saja.
ostergaard
Ini adalah jawaban yang benar untuk pertanyaan yang masih benar di tahun 2018! Sebuah middleware dapat dipasang dengan all () juga ... satu-satunya perbedaan adalah bahwa jalur pemasangan dilucuti saat menjalankan middleware.
Xatian
4

Ya, app.all()dipanggil ketika URI tertentu diminta dengan semua jenis metode permintaan (POST, GET, PUT, atau DELETE)

Di sisi lain, app.use()digunakan untuk middleware apa pun yang mungkin Anda miliki dan dipasang ke awalan jalur, dan akan dipanggil setiap kali URI di bawah rute itu diminta.

Berikut adalah dokumentasi untuk app.all & app.use .

Gurpreet Singh
sumber
terima kasih tapi saya pikir Anda melewatkan app.all wildcard dan app.use jalur root yang membuat mereka hampir sama, bukan? Kecuali bahwa app.all dapat mengambil serangkaian callback dan app.use hanya dapat mengambil satu - bukan?
ostergaard
1

Dua perbedaan semua jawaban di atas tidak cocok.

Pertama: app.allmenerima regex sebagai parameter jalurnya. app.useTIDAK menerima regex.

Yang kedua: app.all(path,handler)atau app[method](path,handler), pawang pathharus sama untuk semua path . Ini, jalur aplikasi [metode] selesai.

app.use(path,hanlder), jika jalur penggunaan selesai, jalur hanlder harus '/'. jika jalur penggunaan adalah awal dari jalur lengkap, jalur penangan harus merupakan jalur lengkap lainnya.

 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
sumber
0

Ada dua perbedaan utama:

1. pencocokan pola (jawaban yang diberikan oleh Palani)
2. next(route)tidak akan berfungsi di dalam badan fungsi middleware yang dimuat menggunakan app.use. Ini dinyatakan dalam tautan dari dokumen:

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

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

Efek kerja next('route')dapat dilihat dari contoh berikut:

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
sumber