Truyền các biến cho phần mềm trung gian tiếp theo bằng next () trong Express.js


200

Chà, câu hỏi của tôi là tôi muốn chuyển một số biến từ phần mềm trung gian đầu tiên sang phần mềm trung gian khác và tôi đã thử làm điều này, nhưng có " req.somevariableđược đưa ra là" không xác định ".


//app.js
..
app.get('/someurl/', middleware1, middleware2)
...

////middleware1
...
some conditions
...
res.somevariable = variable1;
next();
...

////middleware2
...
some conditions
...
variable = req.somevariable;
...

Nên làm việc. Trừ khi đó là một lỗi đánh máy trong câu hỏi mà bạn có thể thất bại bởi vì bạn gán giá trị cho restrong middleware1 và cố gắng lấy nó từ reqtrong middleware2.
Andreas Hultgren

Thankz @AndreasHultgren
user2791897

Local variables are available in middleware via req.app.locals expressjs.com/pt-br/api.html#app.locals
Ronnie Royston

Câu trả lời:


202

Đính kèm biến của bạn với reqđối tượng, không res.

Thay vì

res.somevariable = variable1;

Có:

req.somevariable = variable1;

Như những người khác đã chỉ ra, res.localslà cách truyền dữ liệu thông qua phần mềm trung gian.


13
sử dụng res.locals.variable = var; xem câu trả lời khác
godzsa

1
để truy xuất biến, sử dụng req.res.locals.variable trong chức năng phần mềm trung gian tiếp theo
William Wu

3
@WilliamWu của nó res.locals, không phải req.res.locals.
cchamberlain

2
res.locals.myVarlà con đường để đi
jasonseminara

448

Đây là những gì đối tượng res.locals dành cho. Đặt biến trực tiếp trên đối tượng yêu cầu không được hỗ trợ hoặc ghi lại. res.locals được đảm bảo giữ trạng thái trong suốt vòng đời của một yêu cầu.

đại lý

Một đối tượng có chứa các biến cục bộ phản hồi nằm trong phạm vi yêu cầu và do đó chỉ có sẵn cho (các) chế độ xem được hiển thị trong chu kỳ yêu cầu / phản hồi đó (nếu có). Mặt khác, thuộc tính này giống hệt với app.locals.

Thuộc tính này hữu ích để hiển thị thông tin cấp yêu cầu, chẳng hạn như tên đường dẫn yêu cầu, người dùng được xác thực, cài đặt người dùng, v.v.

app.use(function(req, res, next) {
    res.locals.user = req.user;  
    res.locals.authenticated = !req.user.anonymous;
    next();
});

Để lấy lại biến trong phần mềm trung gian tiếp theo:

app.use(function(req, res, next) {
    if (res.locals.authenticated) {
        console.log(res.locals.user.id);
    }
    next();
});

67
Không biết tại sao điều này không phải là câu trả lời được chấp nhận, đây là những tài liệu cách để thiết lập biến từ middleware trong suốt một yêu cầu.
Sam Holmes

11
res.locals được dự định sẽ được sử dụng bởi các chế độ xem cuối cùng được hiển thị trong vòng đời của yêu cầu, đây là những gì tài liệu đang nói. Nếu bạn không sử dụng lượt xem thì quá mức cần thiết để đưa mọi thứ vào đối tượng địa phương và đó không phải là quy ước. Trong những trường hợp này, tôi có xu hướng khuyến khích mọi người gắn bó với quy ước để chúng ta có thể giảm tải nhận thức trong khi học các khái niệm như Express hoặc yêu cầu vòng đời.
real_ate

2
@real_ate đó là cách sử dụng chính của res.locals, tuy nhiên nó không giải quyết được câu hỏi OP. Việc chuyển các biến phạm vi yêu cầu cho phần mềm trung gian trong tương lai đôi khi là một điều cần thiết, những lần tôi đưa ra thường là về xác thực người dùng trong phần mềm trung gian ban đầu, đặt ra các khiếu nại được chuyển đến phần mềm trung gian phía dưới.
cchamberlain

14
Tài liệu cấp tốc để viết phần mềm trung gian đặt các biến trên reqđối tượng expressjs.com/en/guide/wr-middleware.html . Nhìn vào phầnMiddleware function requestTime
Cá da trơn

3
@goonerify thats may mắn không làm thế nào phản ứng hoạt động. Các phản hồi được truyền bằng cách gọi một thuộc tính chức năng của đối tượng phản hồi res.json({}), v.v., res.localschỉ có sẵn ở mặt sau trong vòng đời của yêu cầu. expressjs.com/en/5x/api.html
cchamberlain

22

Tôi không nghĩ rằng thực tiễn tốt nhất sẽ vượt qua một biến như thế req.YOUR_VAR. Bạn có thể muốn xem xét req.YOUR_APP_NAME.YOUR_VARhoặc req.mw_params.YOUR_VAR.

Nó sẽ giúp bạn tránh ghi đè các thuộc tính khác.

Cập nhật ngày 31 tháng 5 năm 2020

res.locals là những gì bạn đang tìm kiếm, đối tượng nằm trong phạm vi yêu cầu.

Một đối tượng có chứa các biến cục bộ phản hồi nằm trong phạm vi yêu cầu và do đó chỉ có sẵn cho (các) chế độ xem được hiển thị trong chu kỳ yêu cầu / phản hồi đó (nếu có). Mặt khác, thuộc tính này giống hệt với app.locals.

Thuộc tính này hữu ích để hiển thị thông tin cấp yêu cầu, chẳng hạn như tên đường dẫn yêu cầu, người dùng được xác thực, cài đặt người dùng, v.v.


2
Làm thế nào để bạn đề nghị thiết lập req.YOUR_APP_NAME = {}ban đầu? Bạn chỉ cần cố gắng viết thư cho req.YOUR_APP_NAME.someVarbạn sẽ nhận được một lỗi như req.YOUR_APP_NAMEchưa được xác định.
Kousha

2
@Kousha Bạn có thể viết phần mềm trung gian bộ định tuyến ở đầu tập lệnh định tuyến của mình:router.use(function(req,res,next){req.YOUR_APP_NAME = {};next()})
Tomas

Có cách nào để vượt qua nó như là param với hàm next () không? như tiếp theo (myObj)
philx_x

1
@Kousha - Lỗi không xác định của bạn không liên quan gì đến express, đó là lỗi bạn đang cố gán thuộc tính cho một đối tượng không tồn tại. Thông thường để làm điều này, bạn sẽ sử dụng req.APP_NS = req.APP_NS || {}; req.APP_NS.somevar = 'value'.
cchamberlain

1
@philx_x, nếu bạn chuyển bất kỳ tham số nào cho nexthàm, nó sẽ kích hoạt trình xử lý lỗi express 'và thả ra. kiểm tra tài liệu
Merl

7

Đó là bởi vì reqreslà hai đối tượng khác nhau.

Bạn cần tìm thuộc tính trên cùng một đối tượng bạn đã thêm nó vào.


3

Thủ thuật khá đơn giản ... Chu kỳ yêu cầu vẫn còn khá nhiều. Bạn chỉ có thể thêm một biến mới sẽ tạo tạm thời, gọi

app.get('some/url/endpoint', middleware1, middleware2);

Vì bạn có thể xử lý yêu cầu của mình trong phần mềm trung gian đầu tiên

(req, res, next) => {
    var yourvalue = anyvalue
}

Trong phần mềm trung gian 1 bạn xử lý logic của mình và lưu trữ giá trị của bạn như dưới đây:

req.anyvariable = yourvalue

Trong phần mềm trung gian 2, bạn có thể bắt giá trị này từ phần mềm trung gian 1 làm như sau:

(req, res, next) => {
    var storedvalue = req.yourvalue
}

1

Như đã đề cập ở trên, res.locals là một cách tốt (được khuyến nghị) để làm điều này. Xem ở đây để xem hướng dẫn nhanh về cách thực hiện điều này trong Express.

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.