Sự khác biệt giữa app.all ('*') và app.use ('/')


121

Có sự khác biệt hữu ích giữa app.all('*', ... )app.use('/', ...)trong Node.JS Express không?

Câu trả lời:


119

Trong hầu hết các trường hợp, họ sẽ làm việc tương đương. Sự khác biệt lớn nhất là thứ tự áp dụng phần mềm trung gian:

  • app.all() đính kèm với bộ định tuyến của ứng dụng, do đó, nó được sử dụng bất cứ khi nào đạt đến phần mềm trung gian app.router (xử lý tất cả các tuyến phương thức ... GET, POST, v.v.).

THÔNG BÁO: app.router không được dùng nữa trong express 4.x

  • app.use()đính kèm với ngăn xếp phần mềm trung gian chính của ứng dụng, do đó, nó được sử dụng theo thứ tự được chỉ định bởi phần mềm trung gian. ví dụ, nếu bạn đặt nó trước, nó sẽ là thứ đầu tiên chạy. Nếu bạn đặt nó lần cuối, (sau bộ định tuyến), nó thường sẽ không được chạy.

Thông thường, nếu bạn muốn làm một cái gì đó trên toàn cầu cho tất cả các tuyến, app.use () là lựa chọn tốt hơn. Ngoài ra, nó có ít khả năng xảy ra lỗi hơn trong tương lai, vì express 0.4 có thể sẽ bỏ bộ định tuyến ngầm (nghĩa là vị trí của bộ định tuyến trong phần mềm trung gian sẽ quan trọng hơn bây giờ, vì về mặt kỹ thuật bạn thậm chí không phải sử dụng nó ngay bây giờ).


15
Điều này vẫn áp dụng sau Express 4.x? app.router đã bị xóa.
ruffrey

1
Bạn có thể sử dụng next("route")với app.all, nhưng không phải với app.use.
Jozef Mikušinec

Tài liệu @JozefMikusinec dường như đề xuất khác ... expressjs.com/en/guide/wr-middleware.html
musicin3d

Liên kết của bạn không đề cập tiếp theo ('tuyến đường'), nhưng tôi đã xem API, bạn đã đúng.
Jozef Mikušinec

2
@ musicin3d Tôi đã nghiên cứu thêm và tìm thấy vấn đề GitHub này , điều đó xác nhận rằng "next () và next ('route') không có gì khác biệt với app.use" (trích dẫn). Họ nên thay đổi các tài liệu.
Jozef Mikušinec

87

app.use chỉ có một chức năng gọi lại và nó có nghĩa là Middleware. Middleware thường không xử lý yêu cầu và phản hồi, (về mặt kỹ thuật họ có thể) họ chỉ xử lý dữ liệu đầu vào và bàn giao nó cho người xử lý tiếp theo trong hàng đợi.

app.use([path], function)

app.all nhận nhiều cuộc gọi lại và có nghĩa là để định tuyến. với nhiều cuộc gọi lại, bạn có thể lọc yêu cầu và gửi phản hồi. Nó được giải thích trong Bộ lọc trên express.js

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

app.use chỉ xem liệu url bắt đầu với đường dẫn đã chỉ định

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

app.all sẽ khớp đường dẫn hoàn chỉnh

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

17
Ít nhất là trong v4, app.use có một hoặc nhiều chức năng phần mềm trung gian, không phải "chỉ một".
Jess Austin

2
app.use chỉ xem liệu url bắt đầu với đường dẫn được chỉ định hay không, app.all sẽ khớp với đường dẫn hoàn chỉnh. đây là sự khác biệt chính
meizilp

@frogcjn không nên vì nó bỏ qua dấu * và / trong câu hỏi của tôi.
Ostergaard

15
  • ứng dụng

    1. tiêm middlware vào cấu hình bộ điều khiển trước của bạn chẳng hạn: tiêu đề, cookie, phiên, v.v.
    2. phải được viết trước ứng dụng [http_method] nếu không sẽ không được thực thi.
    3. một số cuộc gọi được xử lý theo thứ tự viết
  • ứng dụng

    1. (như ứng dụng [http_method]) được sử dụng để định cấu hình bộ điều khiển của tuyến đường
    2. "Tất cả" có nghĩa là nó áp dụng trên tất cả các phương thức http.
    3. một số cuộc gọi được xử lý theo thứ tự viết

Nhìn vào mẫu mã expressJs này:

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

Đây là nhật ký khi truy cập tuyến đường '/ xin chào':

(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

6
Sau khi chạy ví dụ này nguyên văn trên express 4.x, nó thực sự chạy cả 5 theo thứ tự. Điều này có thể là do những thay đổi trong cách thể hiện trong gần 3 năm kể từ khi nó được viết, nhưng tôi chỉ nghĩ rằng tôi sẽ thêm điều này cho rõ ràng.
Nathan Wiebe

11

Với app.use(), đường dẫn "mount" bị tước và không hiển thị cho chức năng phần mềm trung gian:

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

Các hàm trung gian được gắn kết ( express.static) không được gọi trừ khi req.urlcó chứa tiền tố này ( /static), tại đó nó bị tước khi hàm được gọi.

Với app.all(), không có hành vi đó.


Câu hỏi chỉ hỏi rõ ràng về app.use ('/', ...).
Ostergaard

Đây là câu trả lời chính xác cho câu hỏi vẫn còn đúng trong năm 2018! Một phần mềm trung gian cũng có thể được gắn với tất cả () ... sự khác biệt duy nhất là đường dẫn gắn kết bị tước khi thực hiện phần mềm trung gian.
Xatian

4

Đúng, app.all() được gọi khi một URI cụ thể được yêu cầu với bất kỳ loại phương thức yêu cầu nào (POST, GET, PUT hoặc DELETE)

Mặt khác app.use() được sử dụng cho bất kỳ phần mềm trung gian nào bạn có thể có và nó gắn vào tiền tố đường dẫn và sẽ được gọi bất cứ khi nào một URI theo tuyến đường đó được yêu cầu.

Đây là tài liệu cho app.all & app.use .


cảm ơn nhưng tôi nghĩ rằng bạn đã bỏ lỡ app.all wildcard và app.use đường dẫn gốc khiến chúng khá giống nhau chính xác phải không? Ngoại trừ app.all có thể mất một loạt các cuộc gọi lại và app.use chỉ có thể mất một - phải không?
Ostergaard

1

Hai sự khác biệt tất cả các câu trả lời trên không metion.

Fisrt one: app.allchấp nhận regex làm tham số đường dẫn của nó. app.useKHÔNG chấp nhận một regex.

Cái thứ hai: app.all(path,handler)hoặc app[method](path,handler), handler pathphải giống với tất cả path . Đây là, đường dẫn của ứng dụng [phương thức] đã hoàn tất.

app.use(path,hanlder), nếu đường dẫn của việc sử dụng hoàn tất, đường dẫn của hanlder phải là '/'. Nếu đường dẫn sử dụng là điểm bắt đầu của đường dẫn hoàn chỉnh, đường dẫn xử lý phải là phần còn lại của đường dẫn hoàn chỉnh.

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

0

Có hai điểm khác biệt chính:

1. khớp mẫu (câu trả lời do Palani đưa ra)
2. next(route)sẽ không hoạt động bên trong thân hàm của phần mềm trung gian được tải bằng cách sử dụng app.use. Điều này được nêu trong liên kết từ các tài liệu:

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

Liên kết: http://expressjs.com/en/guide/USE-middleware.html

Hiệu quả làm việc của next('route')có thể được nhìn thấy từ ví dụ sau:

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();});
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.