Expressware'de ara katman yazılımı ve app.use ne anlama geliyor?


228

Gördüğüm hemen hemen her Express uygulaması app.useara katman yazılımı için bir açıklama var, ancak ara katman yazılımının gerçekte ne olduğunu ve app.useifadenin ne yaptığını net ve özlü bir açıklama bulamadım . Ekspres dokümanlar bile bu konuda biraz belirsizdir. Bu kavramları bana açıklayabilir misiniz lütfen?


3
referans için benzer bir soru (bu daha önce oluşturuldu tho): stackoverflow.com/questions/11321635/…
ericsoco

43
^ Ha! Bu iki soru yorumlarda birbirlerine atıfta bulunmaktadır.
Julian H. Lam

17
Bu bir Dairesel Referans.
Steve K

6
Express.js Middleware Demystified Konu hakkında harika bir blog yazısı. Bu daha önce buraya kopyalanmıştı, ki bu intihal tabii ki, ama orijinal yazı hala gerçekten yararlıdır, bu yüzden buraya bir bağlantı bırakıyorum.
totymedli

1
Express.js ara katman yazılımı hakkında bir makale yazdım. Bağlantı: nodexplained.com/blog-detail/2017/12/31/…
shrawan_lakhe

Yanıtlar:


111

ara katman

Yeni bir projede ara katman kavramını ayırarak yarı yoldayım.

Ara katman yazılımı, içinden geçmeniz gereken bir eylem yığını tanımlamanızı sağlar. Ekspres sunucuların kendisi bir orta yol yığınıdır.

// express
var app = express();
// middleware
var stack = middleware();

Daha sonra arayarak ara katman yığınına katmanlar ekleyebilirsiniz. .use

// express
app.use(express.static(..));
// middleware
stack.use(function(data, next) {
  next();
});

Orta katman yığınındaki bir katman, n parametresini (ekspres için 2, req& res) alan bir nextişlev ve bir işlevdir.

Middleware, katmanın bir miktar hesaplama yapmasını, parametreleri artırmasını ve ardından çağırmasını bekler next.

Bir yığın, siz işlemediğiniz sürece hiçbir şey yapmaz. Express, sunucuya her gelen HTTP isteği yakalandığında yığını işleyecektir. Ara katman yazılımı ile yığını elle yönetirsiniz.

// express, you need to do nothing
// middleware
stack.handle(someData);

Daha eksiksiz bir örnek:

var middleware = require("../src/middleware.js");

var stack = middleware(function(data, next) {
    data.foo = data.data*2;
    next();
}, function(data, next) {
    setTimeout(function() {
        data.async = true;
        next();
    }, 100)
}, function(data) {
    console.log(data);
});

stack.handle({
    "data": 42
})

Ekspres terimlerle, gelen her HTTP isteği için ekspresin işlemesini istediğiniz bir işlem yığını tanımlarsınız.

Ekspres açısından (bağlanmak yerine) global bir ara katman yazılımına ve yola özgü ara katman yazılımına sahipsiniz. Bu, gelen her HTTP isteğine bir ara katman yığını ekleyebileceğiniz veya yalnızca belirli bir yolla etkileşime giren HTTP isteklerine ekleyebileceğiniz anlamına gelir.

Express & Middleware'in gelişmiş örnekleri:

// middleware 

var stack = middleware(function(req, res, next) {
    users.getAll(function(err, users) {
        if (err) next(err);
        req.users = users;
        next();  
    });
}, function(req, res, next) {
    posts.getAll(function(err, posts) {
        if (err) next(err);
        req.posts = posts;
        next();
    })
}, function(req, res, next) {
    req.posts.forEach(function(post) {
        post.user = req.users[post.userId];
    });

    res.render("blog/posts", {
        "posts": req.posts
    });
});

var app = express.createServer();

app.get("/posts", function(req, res) {
   stack.handle(req, res); 
});

// express

var app = express.createServer();

app.get("/posts", [
    function(req, res, next) {
        users.getAll(function(err, users) {
            if (err) next(err);
            req.users = users;
            next();  
        });
    }, function(req, res, next) {
        posts.getAll(function(err, posts) {
            if (err) next(err);
            req.posts = posts;
            next();
        })
    }, function(req, res, next) {
        req.posts.forEach(function(post) {
            post.user = req.users[post.userId];
        });

        res.render("blog/posts", {
            "posts": req.posts
        });
    }
], function(req, res) {
   stack.handle(req, res); 
});

4
Hmm ... bu durumda ara katman yazılımı kendi kütüphaneniz mi yoksa ekspresinizin bir parçası mı?
iZ.

5
Güzel. Hala app.use()sözdizimiyle biraz kafam karıştı . Ara katman yazılımının gerçek dönüş değeri nedir useve bununla ne yapar ?
iZ.

9
@ iZ use bunu bir yığına ekler. Sonra her istek yığının içinden geçer.
Raynos

7
@Raynos, projenize olan bağlantı "ara katman yazılımı" bozuldu.
Lee

1
@Raynos ama Expressware hala hala kullanılan yazılım görüyorum? ne demek bu nuked?
Timo Huovinen

60

Bir şeyleri basitleştirdikten sonra, bir web sunucusu bir istek alan ve bir yanıt çıkaran bir işlev olarak görülebilir. Dolayısıyla, bir web sunucusunu işlev olarak görüntülerseniz, birkaç parça halinde düzenleyebilir ve kompozisyonlarını orijinal işlev olacak şekilde daha küçük işlevlere ayırabilirsiniz.

Middlewares, başkalarıyla oluşturabileceğiniz daha küçük işlevlerdir ve bariz faydası onları yeniden kullanabilmenizdir.


33

Önceki cevaplarda belirtilmeyen bir şeyi eklemek için geç bir cevap ekliyorum.

Şimdiye kadar, ara katman yazılımının istemci isteği ile sunucu yanıtı arasında çalıştığı açıktır . Gereken en yaygın ara katman yazılımı işlevi, hata yönetimi, veritabanı etkileşimi, statik dosyalardan veya diğer kaynaklardan bilgi almadır. Ara katman yığını üzerinde ilerlemek için bir sonraki geri arama çağrılmalıdır, ara katman fonksiyonunun sonunda akışta bir sonraki adıma geçmek için görebilirsiniz.

app.useYaklaşımı kullanabilir ve bunun gibi bir akışınız olabilir :

var express = require('express'),
    app = express.createServer(),                                                                                                                                                 
    port = 1337;

function middleHandler(req, res, next) {
    console.log("execute middle ware");
    next();
}

app.use(function (req, res, next) {
    console.log("first middle ware");                                                                                                             
    next();
});

app.use(function (req, res, next) {
    console.log("second middle ware");                                                                                                             
    next();
});

app.get('/', middleHandler, function (req, res) {
    console.log("end middleware function");
    res.send("page render finished");
});

app.listen(port);
console.log('start server');

ancak başka bir yaklaşım da kullanabilir ve her ara katmanı işlev bağımsız değişkenleri olarak iletebilirsiniz. Burada, midleware'inresponse istemciye geri gönderilmeden önce Twitter, Github ve Blog akışını aldığı MooTools Nodejs web sitesinden bir örnek . İşlevlerin bağımsız değişken olarak nasıl iletildiğine dikkat edin app.get('/', githubEvents, twitter, getLatestBlog, function(req, res){. Kullanma app.getsadece GET istekleri için çağrılır, app.usetüm istekler için çağrılır.

// github, twitter & blog feeds
var githubEvents = require('./middleware/githubEvents')({
    org: 'mootools'
});
var twitter = require('./middleware/twitter')();
var blogData = require('./blog/data');
function getLatestBlog(req, res, next){
    blogData.get(function(err, blog) {
        if (err) next(err);
        res.locals.lastBlogPost = blog.posts[0];
        next();
    });
}

// home
app.get('/', githubEvents, twitter, getLatestBlog, function(req, res){
    res.render('index', {
        title: 'MooTools',
        site: 'mootools',
        lastBlogPost: res.locals.lastBlogPost,
        tweetFeed: res.locals.twitter
    });
});

2
Express.js rota tabanlı (NOT Router tabanlı) ara katman yazılımı montajı destekleyip desteklemediğine bir cevap mı arıyorsunuz? Görünüşe göre cevabında göstermişsin.
Selçuk

Yukarıdaki örneğinizi açıklayabilir misiniz ?, bu kadar çok işlevi app.get (...) 'a nasıl aktarabilirsiniz ve bunlara hangi sıra denir?
Tanner Summers

2
Merhaba @ TannerSummers, .get()yöntem 3 tür argüman alır: ilk, son ve orta olanlar. Dahili olarak 2'den fazla argüman olup olmadığını tespit eder ve bunları (ortadaki) soldan sağa çağıran ara katman işlevleri olarak kullanır.
Sergio

22

expressjs kılavuzu sorunuza oldukça temiz bir cevabı var, kesinlikle okumanızı tavsiye ederim, kılavuzun kısa bir parçasını gönderiyorum, rehber oldukça iyi.

Express uygulamalarında kullanmak için ara katman yazılımı yazma

genel bakış

Ara katman yazılımı işlevleri, istek nesnesine ( req ), yanıt nesnesine ( res ) ve uygulamanın istek yanıt döngüsünde bir sonraki işleveerişimi olanişlevlerdir. Sonraki işlev, Express yönlendiricisinde, çağrıldığında geçerli ara katman yazılımını takip eden ara katman yazılımını yürüten bir işlevdir.

Ara katman yazılımı işlevleri aşağıdaki görevleri gerçekleştirebilir:

  • Herhangi bir kodu yürütün.
  • İstekte ve yanıt nesnelerinde değişiklik yapın.
  • İstek-yanıt döngüsünü sonlandırın.
  • Yığında bir sonraki ara katman yazılımını çağırın.

Geçerli ara katman yazılımı işlevi istek yanıt döngüsünü sonlandırmazsa, denetimi bir sonraki ara katman yazılımı işlevine geçirmek için next () öğesini çağırmalıdır . Aksi takdirde, istek askıda bırakılır.

resim açıklamasını buraya girin

Misal

İşte basit bir “Hello World” Express uygulamasına bir örnek. Bu makalenin geri kalan kısmı tanımlayacak ve uygulamaya iki ara katman yazılımı işlevi ekleyecektir: biri basit bir günlük iletisi yazdıran myLogger ve diğeri HTTP isteğinin zaman damgasını görüntüleyen requestTime 1 olarak adlandırılır .

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

app.get('/', function (req, res) {
  res.send('Hello World!')
})

app.listen(3000)   

Ara katman yazılımı işlevi myLogger

“MyLogger” adlı ara katman işlevine basit bir örnek. Uygulamaya bir istek iletildiğinde bu işlev yalnızca “LOGGED” yazdıracaktır. Ara katman yazılımı işlevi myLogger adlı bir değişkene atanır.

var myLogger = function (req, res, next) {
  console.log('LOGGED')
  next()
}

Yukarıdaki çağrıya sonraki () çağrısına dikkat edin . Bu işlevin çağrılması, uygulamadaki bir sonraki ara katman yazılımı işlevini çağırır. Sonraki () fonksiyonu node.js veya Ekspres API bir parçası değildir, ancak katman işleve üçüncü bir argümandır. Sonraki () fonksiyonu herhangi bir şekilde adlandırılabilir, ancak Kongre tarafından her zaman “next” olarak adlandırılır. Karışıklığı önlemek için her zaman bu sözleşmeyi kullanın.

Ara katman yazılımı işlevini yüklemek için, ara katman yazılımı işlevini belirterek app.use () öğesini çağırın . Örneğin, aşağıdaki kod myLogger ara katman yazılımı işlevini kök yoluna (/) giden yoldan önce yükler .

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

var myLogger = function (req, res, next) {
  console.log('LOGGED')
  next()
}

app.use(myLogger)

app.get('/', function (req, res) {
  res.send('Hello World!')
})

app.listen(3000)

Uygulama her istek aldığında, terminale “LOGGED” mesajını yazdırır.

Ara katman yazılımı yükleme sırası önemlidir: önce yüklenen ara katman yazılımı işlevleri de ilk olarak yürütülür.

Eğer myLogger kök yoluna rota sonra yüklenir, istek asla onu ulaşır ve kök yolunun güzergah işleyicisi istek-yanıt döngüsü sona erer, çünkü uygulama, “kaydediliyor” yazdırmaz.

Ara katman yazılımı işlevi myLogger basitçe bir ileti yazdırır, ardından isteği sonraki () işlevini çağırarak yığın içindeki bir sonraki katman yazılımı işlevine iletir .


  1. Bu mesaj sadece rehberlik orijinal expressjs gidebiliriz başka yazı için myLogger ortakatmanlar içerecektir burada .


1
Çok güzel bir açıklama.
Drumbeg

Burada ekspres sitede mevcuttur expressjs.com/en/guide/writing-middleware.html , gerçekten çok iyi. Acaba neden kimse bundan bahsetmedi.
Suraj Jain

2
Güzel bir. Burada gördüğüm en açık açıklama ve evet, hiç kimsenin referans vermediği garip!
Drumbeg

1
Güzel açıkladı
Rehan Shikkalgar

Ara katman yazılımı yükleme sırası önemlidir: önce yüklenen ara katman yazılımı işlevleri de ilk olarak yürütülür. : Bu çok önemli bir not. Bundan başka cevap gelmiyor. Sadece python üzerinde çalışan bir acemi için, bu şeylere hiç rastlanmamış olabilir.
Tessaracter

11

===== Çok çok basit bir açıklama =====

Middlewares genellikle Express.js çerçevesi bağlamında kullanılır ve node.js için temel bir kavramdır. Özetle, temelde uygulamanızın istek ve yanıt nesnelerine erişimi olan bir işlev. Bunu düşünmek istediğim yol, talebin uygulama tarafından ele alınmadan önce geçtiği bir dizi 'kontrol / ön ekran'. Örneğin, Middlewares, isteğin uygulamaya geçmeden önce kimliğinin doğrulanıp doğrulanmadığını belirlemek ve istek doğrulanmamışsa veya her isteği günlüğe kaydetmek için oturum açma sayfasını döndürmek için uygun olacaktır. Çeşitli işlevsellik sağlayan birçok üçüncü taraf ara yazılım mevcuttur.

Basit Middleware örneği:

var app = express();
app.use(function(req,res,next)){
    console.log("Request URL - "req.url);
    next();
}

Yukarıdaki kod, gelen her istek için yürütülür ve istek url'sini günlüğe kaydeder; next () yöntemi temel olarak programın devam etmesine izin verir. Next () işlevi çağrılmazsa, program daha fazla ilerlemez ve ara katman yazılımının yürütülmesinde durur.

Birkaç Middleware Gotchas:

  1. İsteğiniz her birini sıralı bir sırayla gerçekleştireceğinden, uygulamanızdaki orta sınıfların sırası önemlidir.
  2. Ara katman yazılımı işlevinizde next () yöntemini çağırmayı unutmanız, isteğinizin işlenmesini durdurabilir.
  3. Ara katman işlevindeki req ve res nesnelerini değiştirmek, değişikliği uygulamanın req ve res kullanan diğer bölümleri tarafından kullanılabilir yapacaktır.

1
Çok teşekkür ederim! bunu anlamak için şimdiye kadarki en iyi açıklama bu. Bir soru, ara katman yazılımı ile bazı kod okuyorum ve çağırmıyor next()ama return next(). Fark ne?
KansaiRobot

Nazik sözler için çok teşekkürler ... Yapacağız next()çünkü bir sonraki ara yazılım çağrılmasını istiyoruz, sanmıyorum next()ya return next()da herhangi bir fark yaratmalıyız! Hala kodun ne olduğuna bağlı ...
Vaibhav Bacchav

7

Middlewares, giriş / kaynaktan sonra nihai çıktı olabilecek veya döngü tamamlanana kadar bir sonraki ara yazılım tarafından kullanılabilecek bir çıkış ürettikten sonra ortada yürütülen işlevlerdir.

Bu, tamamlanana, değerlendirilene veya reddedilene kadar hareket ettikçe değiştirildiği bir montaj hattından geçen bir ürün gibidir.

Bir ara katman yazılımı bazı değerlerin üzerinde çalışmasını bekler (yani parametre değerleri) ve bazı mantığa bağlı olarak ara katman yazılımı bir sonraki ara katmanı çağırır veya aramaz veya istemciye bir yanıt gönderir.

Ara katman yazılımı kavramını hala kavrayamıyorsanız, Dekoratör veya Komut kalıpları Zinciri'ne benzer bir şekilde.


5

Ara katman yazılımı, kullanıcı tanımlı işleyici çağrılmadan önce Express js yönlendirme katmanı tarafından çağrılan zincirleme işlevlerin bir alt kümesidir. Ara katman yazılımı işlevleri, istek ve yanıt nesnelerine tam erişime sahiptir ve bunlardan herhangi birini değiştirebilir.

Ara katman yazılımı zinciri her zaman tanımlandığı sırayla çağrılır, bu nedenle belirli bir ara katman yazılımının tam olarak ne yaptığını bilmeniz hayati önem taşır.
Bir ara katman işlevi sona erdiğinde, sonraki bağımsız değişkenini işlev olarak çağırarak zincirdeki bir sonraki işlevi çağırır.
Zincirin tamamı yürütüldükten sonra, kullanıcı istek işleyicisi çağrılır.


1

İşleri basit tutun adamım!

Not: Cevap, ExpressJS yerleşik arabuluculuk vakaları ile ilgilidir, ancak farklı tanımlar ve ara yazılımların kullanım durumları vardır.

Benim açımdan, ara katman yazılımı yardımcı program veya yardımcı işlevler gibi davranır, ancak etkinleştirilmesi ve kullanımı,app.use('path', /* define or use builtin middleware */) istemcimizin her HTTP isteği için gerekli olan çok yaygın görevleri yapmak için bazı kodlar yazmamızı istemeyen tamamen isteğe bağlıdır . çoğu uygulamada çok yaygın olan çerezleri, CSRF jetonlarını ve ... işlemek gibi, ara katman yazılımı, bunları bir yığın, sıra veya işlem sırasında istemcimizin her HTTP isteği için yapmamıza yardımcı olabilir ve işlemin sonucunu şu şekilde sağlayabilir: tek bir birim istemci isteği .

Misal:

Müşterilerin isteklerini kabul etmek ve isteklerine göre cevap vermek web sunucusu teknolojisinin doğasıdır.

Sadece "Merhaba dünya!" web sunucumuzun kök URI'sine bir GET HTTP isteği metni çok basit bir senaryodur ve başka bir şeye ihtiyaç duymaz, bunun yerine şu anda oturum açmış olan kullanıcıyı kontrol edip "Merhaba, Kullanıcı Adı!" bu durumda her zamankinden daha fazla bir şeye ihtiyaç duyarız. bazı ilgili verilerle.

Birisine yardım etmeyi umuyoruz!


-1

Çok temel terimde ben böyle açıklamak istiyorsanız ben bu traversymedia youtube kanalı ekspres crash ders öğrenin.
tamam orta eşya, rotanıza böyle bir çağrı yaptıktan sonra çalışan bir işlevdir.

var logger = function(req, res, next){
   console.log('logging...');
   next();
}

app.use(logger);

Bu günlükçü işlevi, sayfanızı her yenilediğinizde yürütülür; bu, sayfanızın herhangi bir işlem çağrısı gerçekleştirildikten sonra yapmanız gereken herhangi bir şeyi yazabileceğiniz, temelde her şeyi sıfırlayabileceğiniz anlamına gelir. ve bu ara katman yazılımını rota işlevi ara katman katmanı sırasına koymadan önce gerçekten önemlidir veya çalışmaz

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.