wake-up-neo.com

Was bedeuten Middleware und Anwendungen in Expressjs?

Fast jede Express-App, die ich sehe, hat eine app.use-Anweisung für Middleware, aber ich habe keine klare und präzise Erklärung dafür gefunden, was Middleware eigentlich ist und was die app.use-Anweisung tut. Sogar die Express-Dokumente selbst sind hier etwas vage. Kannst du mir diese Konzepte bitte erklären?

204
iZ.

Middleware

Ich bin auf halbem Weg durch die Trennung des Konzeptes der Middleware in einem neuen Projekt. 

Mit der Middleware können Sie einen Stapel von Aktionen definieren, die Sie durchlaufen sollen. Express-Server selbst sind ein Stapel von Middlewares.

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

Dann können Sie dem Middleware-Stack Layer hinzufügen, indem Sie .use aufrufen.

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

Eine Schicht im Middleware-Stack ist eine Funktion, die n Parameter (2 für express, req & res) und eine next-Funktion verwendet.

Die Middleware erwartet, dass die Schicht einige Berechnungen durchführt, die Parameter erweitert und dann next aufgerufen wird.

Ein Stack macht nichts, wenn Sie nicht damit umgehen. Der Stapel wird von Express jedes Mal verarbeitet, wenn eine eingehende HTTP-Anforderung auf dem Server erfasst wird. Mit Middleware handhaben Sie den Stack manuell.

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

Ein vollständigeres Beispiel:

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

Express ausgedrückt definieren Sie einfach einen Stapel von Vorgängen, die express für jede eingehende HTTP-Anforderung behandeln soll.

In Bezug auf Express (statt Verbinden) verfügen Sie über globale Middleware und routenspezifische Middleware. Dies bedeutet, dass Sie einen Middleware-Stack an alle eingehenden HTTP-Anforderungen oder nur an HTTP-Anforderungen anhängen können, die mit einer bestimmten Route interagieren.

Fortgeschrittene Beispiele für Express- und Middleware:

// 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); 
});
99
Raynos

Nach der Vereinfachung kann ein Webserver als Funktion betrachtet werden, die eine Anfrage aufnimmt und eine Antwort ausgibt. Wenn Sie also einen Webserver als Funktion anzeigen, können Sie ihn in mehrere Teile aufteilen und in kleinere Funktionen aufteilen, so dass deren Zusammensetzung die ursprüngliche Funktion ist.

Middlewares sind die kleineren Funktionen, die Sie mit anderen zusammenstellen können, und der offensichtliche Vorteil ist, dass Sie sie wiederverwenden können.

55
Barum Rho

Ich füge eine späte Antwort hinzu, um etwas hinzuzufügen, das nicht in den vorherigen Antworten erwähnt wurde.

Mittlerweile sollte klar sein, dass Middleware-Funktion (en) zwischen der client-Anforderung und der Server-Antwort ausgeführt wird. Die am häufigsten benötigten Middleware-Funktionen sind Fehlerverwaltung, Datenbankinteraktion, Abrufen von Informationen aus statischen Dateien oder anderen Ressourcen. Um sich auf dem Middleware-Stack zu bewegen, muss der nächste Callback aufgerufen werden. Sie können ihn am Ende der Middleware-Funktion sehen, um zum nächsten Schritt im Ablauf zu gelangen.

Sie können den app.use-Ansatz verwenden und haben einen Fluss wie folgt :

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

sie können jedoch auch einen anderen Ansatz verwenden und jede Middleware als Funktionsargumente übergeben. Hier ist ein Beispiel von der MooTools Nodejs-Website wo Midleware den Twitter-, Github- und Blog-Fluss abruft, bevor die response an den Client zurückgesendet wird. Beachten Sie, wie die Funktionen in app.get('/', githubEvents, Twitter, getLatestBlog, function(req, res){ als Argumente übergeben werden. Mit app.get wird nur für GET-Anfragen aufgerufen, app.use wird für alle Anfragen aufgerufen. 

// 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
    });
});
27
Sergio

expressjs guide hat eine ziemlich gute Antwort auf Ihre Frage. Ich empfehle Ihnen nachdrücklich, dies zu lesen. Ich poste einen kurzen Ausschnitt des Guides. Der Guide ist ziemlich gut.

Schreiben von Middleware zur Verwendung in Express-Apps

Überblick

Middleware Funktionen sind Funktionen, die Zugriff auf das Anfrageobjekt ( req), das Antwortobjekt ( res) und die nächste Funktion im Request-Response-Zyklus der Anwendung. Die nächste Funktion ist eine Funktion im Express-Router, die beim Aufrufen die Middleware ausführt, die der aktuellen Middleware folgt.

Middleware-Funktionen können die folgenden Aufgaben ausführen:

  • Führen Sie einen beliebigen Code aus.
  • Nehmen Sie Änderungen an den Anforderungs- und Antwortobjekten vor.
  • Beenden Sie den Request-Response-Zyklus.
  • Rufen Sie die nächste Middleware im Stapel auf.

Wenn die aktuelle Middleware-Funktion den Request-Response-Zyklus nicht beendet, muss next () aufgerufen werden, um die Steuerung an die nächste Middleware-Funktion zu übergeben. Andernfalls bleibt die Anfrage hängen.

enter image description here

Beispiel

Hier ist ein Beispiel für eine einfache Express-Anwendung „Hello World“. Der Rest dieses Artikels definiert und fügt der Anwendung zwei Middleware-Funktionen hinzu: eine mit dem Namen myLogger, die eine einfache Protokollnachricht ausgibt, und eine andere mit dem Namen requestTime1 Damit wird der Zeitstempel der HTTP-Anforderung angezeigt.

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

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

app.listen(3000)   

Middleware-Funktion myLogger

Hier ist ein einfaches Beispiel für eine Middleware-Funktion namens "myLogger". Diese Funktion druckt nur "GELOGGT", wenn eine Anfrage an die App durchgelaufen ist. Die Middleware-Funktion ist einer Variablen namens myLogger zugeordnet.

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

Beachten Sie den obigen Aufruf von next (). Durch Aufrufen dieser Funktion wird die nächste Middleware-Funktion in der App aufgerufen. Die Funktion next () ist kein Teil der Node.js- oder Express-API, sondern das dritte Argument, das an die Middleware-Funktion übergeben wird. Die Funktion next () kann beliebig benannt werden, wird aber konventionell immer als "next" bezeichnet. Verwenden Sie immer diese Konvention, um Verwirrung zu vermeiden.

Rufen Sie zum Laden der Middleware-Funktion app.use () auf und geben Sie die Middleware-Funktion an. Der folgende Code lädt beispielsweise die Middleware-Funktion myLogger vor der Route zum Stammpfad (/).

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)

Jedes Mal, wenn die App eine Anfrage erhält, druckt sie die Nachricht „LOGGED“ auf das Terminal.

Die Reihenfolge des Ladens der Middleware ist wichtig: Zuerst geladene Middleware-Funktionen werden ebenfalls zuerst ausgeführt.

Wenn myLogger nach der Route zum Root-Pfad geladen wird, erreicht die Anfrage diese nie und die App gibt nicht "LOGGED" aus, da der Routen-Handler des Root-Pfades die Anfrage-Antwort beendet Zyklus.

Die Middleware-Funktion myLogger gibt einfach eine Nachricht aus und leitet die Anforderung durch Aufrufen der Funktion next () an die nächste Middleware-Funktion im Stack weiter.




  1. Dieser Beitrag wird nur myLogger-Middleware enthalten. Für weitere Beiträge können Sie zum Original-Express-Handbuch hier gehen.
14
Suraj Jain

Sehr einfache Erklärung =====

Middlewares werden häufig im Kontext des Express.js-Frameworks verwendet und sind ein grundlegendes Konzept für node.js. Kurz gesagt, es ist im Grunde eine Funktion, die Zugriff auf die Anforderungs- und Antwortobjekte Ihrer Anwendung hat. Ich möchte gerne darüber nachdenken, ist eine Reihe von "Checks/Pre-Screens", die die Anforderung durchläuft, bevor sie von der Anwendung bearbeitet wird. Beispielsweise wäre Middlewares eine gute Wahl, um zu bestimmen, ob die Anforderung authentifiziert wird, bevor sie zur Anwendung übergeht, und die Anmeldeseite zurückzugeben, wenn die Anforderung nicht authentifiziert ist, oder um jede Anforderung zu protokollieren. Es sind viele Mittelprodukte von Drittanbietern verfügbar, die eine Vielzahl von Funktionen ermöglichen.

Einfaches Middleware-Beispiel:

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

Der obige Code wird für jede eingehende Anforderung ausgeführt und protokolliert die Anforderungs-URL. Mit der next () -Methode kann das Programm im Wesentlichen fortgesetzt werden. Wenn die next () - Funktion nicht aufgerufen wird, wird das Programm nicht weiter ausgeführt und hält an der Ausführung der Middleware an.

Ein paar Middleware Gotchas:

  1. Die Reihenfolge der Middlewares in Ihrer Anwendung ist von Belang, da die Anforderung jedes in einer sequentiellen Reihenfolge durchlaufen würde.
  2. Wenn Sie vergessen, die next () -Methode in Ihrer Middleware-Funktion aufzurufen, kann die Verarbeitung Ihrer Anfrage abgebrochen werden.
  3. Jede Änderung der Objekte req und res in der Middleware-Funktion würde die Änderung für andere Teile der Anwendung verfügbar machen, die req und res verwenden
7
Vaibhav Bacchav

Middlewares sind Funktionen, die in der Mitte ausgeführt werden, nachdem die Eingabe/Quelle dann eine Ausgabe erzeugt, die die endgültige Ausgabe sein kann oder von der nächsten Middleware verwendet werden kann, bis der Zyklus abgeschlossen ist. 

Es ist wie ein Produkt, das eine Fertigungslinie durchläuft, in der es während des Vorgangs modifiziert wird, bis es abgeschlossen, ausgewertet oder abgelehnt wird.

Eine Middleware erwartet einen Wert, an dem gearbeitet werden kann (d. H. Parameterwerte) und basierend auf einer bestimmten Logik wird die Middleware die nächste Middleware aufrufen oder nicht aufrufen oder eine Antwort an den Client zurücksenden.

Wenn Sie das Middleware-Konzept immer noch nicht verstehen können, ähnelt es den Decorator- oder Chain-of-Pattern-Mustern.

6
naz

Middleware ist eine Teilmenge verketteter Funktionen, die von der Express js-Routing-Schicht aufgerufen werden, bevor der benutzerdefinierte Handler aufgerufen wird. Middleware-Funktionen haben vollen Zugriff auf die Anforderungs- und Antwortobjekte und können beide ändern.

Die Middleware-Kette wird immer in der genauen Reihenfolge aufgerufen, in der sie definiert wurde. Daher ist es wichtig, dass Sie genau wissen, was eine bestimmte Middleware tut.
Sobald eine Middleware-Funktion abgeschlossen ist, ruft sie die nächste Funktion in der Kette auf, indem das nächste Argument als Funktion aufgerufen wird. 
Nachdem die gesamte Kette ausgeführt wurde, wird der Benutzeranforderungshandler aufgerufen.

5
rishabh dev

Halte die Dinge einfach, Mann!

Hinweis: Die Antwort bezieht sich auf die in ExpressJS eingebauten Middlware-Fälle, es gibt jedoch unterschiedliche Definitionen und Anwendungsfälle für Middleware.

Aus meiner Sicht ist Middleware fungiert als Hilfs- oder Hilfsfunktionen, aber ihre Aktivierung und Verwendung ist vollständig optional durch Verwendung der app.use('path', /* define or use builtin middleware */), die nicht von uns Code schreiben soll, um sehr häufige Aufgaben auszuführen, die erforderlich sind Für jede HTTP-Anfrage unseres Clients, wie z. B. die Verarbeitung von Cookies, CSRF-Token und ..., die in den meisten Anwendungen sehr häufig vorkommen, die Middleware kann uns also helfen, dies für jede HTTP-Anfrage unseres Clients in einem bestimmten Stapel, in einer bestimmten Reihenfolge oder Reihenfolge auszuführen von Operationen liefern dann das Ergebnis des Prozesses als einzelne Einheit einer Clientanforderung.

Beispiel:

Das Akzeptieren von Client-Anfragen und das Bereitstellen von Rückantworten entsprechend ihren Anforderungen ist die Art der Webserver-Technologie.

Stellen Sie sich vor, wir würden nur mit "Hallo, Welt!" Antworten. Der Text für eine GET-HTTP-Anforderung an den Root-URI unseres Webservers ist ein sehr einfaches Szenario und benötigt nichts anderes. Stattdessen überprüfen wir den aktuell angemeldeten Benutzer und antworten mit "Hallo, Benutzername!". braucht etwas mehr als üblich in diesem Fall benötigen wir eine Middleware, um alle Metadaten der Clientanfragen zu verarbeiten und uns die aus der Clientanforderung abgerufenen Identifikationsdaten bereitzustellen. Danach können wir unseren aktuellen Benutzer eindeutig identifizieren und auf ihn antworten/mit einigen verwandten Daten.

Hoffe es, jemandem zu helfen!

1
MNR

Wenn ich es so erklären möchte, lerne ich dies von Traversymedia Youtube Channel Express Crash Course. 
ok so Middleware ist eine Funktion, die ausgeführt wird, nachdem Sie Ihre Route so aufgerufen haben.

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

app.use(logger);

Diese Logger-Funktion wird bei jeder Aktualisierung der Seite ausgeführt. Das bedeutet, dass Sie alles in die Seite schreiben können, das erforderlich ist, nachdem Ihre Seite einen beliebigen Vorgang gerendert hat. Alles im Grunde zurücksetzen. und legen Sie diese Middleware vor die Reihenfolge der Routenfunktionen der Middleware, oder es funktioniert nicht

0