Dein erstes Middleware
Teil des Abschnitts Express-Grundlagen der Node.js-Journey von Coddy. Lektion 13 von 23.
Manche Aufgaben fallen bei jeder Anfrage an, etwa eine Zeile ins Protokoll zu schreiben, und sie in jede Route zu kopieren, würde nie enden. Jede Anfrage hat eine Methode in req.method: GET, um etwas abzurufen, POST, um etwas zu senden.
let visits = 0;
app.use((req, res, next) => {
visits++;
next();
});Eine Funktion, die an app.use übergeben wird, ist Middleware: Express führt sie bei jeder Anfrage und in der Reihenfolge aus, in der sie hinzugefügt wurde, bevor die darunterstehenden Routen ausgeführt werden. Sie erhält ein drittes Argument, next. Durch den Aufruf von next() wird die Anfrage an das weitergegeben, was als Nächstes kommt. Eine Middleware, die weder antwortet noch next() aufruft, lässt die Anfrage für immer warten.
express.static aus dem letzten Kapitel ist ebenfalls Middleware: Sie antwortet, wenn sie eine Datei findet, und ruft next() auf, wenn sie keine findet.
Aufgabe
EinfachDu möchtest für jede Anfrage, die dein Server erhält, eine Protokollzeile, damit du sehen kannst, wonach Besucher fragen.
- Füge in
server.jsdirekt nachconst app = express();eine Middleware mitapp.usehinzu. Dort platziert, wird sie vor jeder Route ausgeführt. - Für jede Anfrage gibt sie eine Zeile in der Konsole aus: die Methode der Anfrage, ein Leerzeichen und anschließend ihren Pfad. Eine Anfrage an
/recipes/2gibtGET /recipes/2aus. Die Methode steht inreq.method(GET,POSTund so weiter) und der Pfad inreq.url. - Nach der Ausgabe ruft sie
next()auf, damit die Anfrage zu den Routen weitergeleitet wird.
Probier es aus: Drücke auf „Spielen“ und sende /recipes/2. Du solltest Pancakes sehen, und in der Konsole wird GET /recipes/2 angezeigt. Sende /api/recipes: Die Liste wie gewohnt und GET /api/recipes in der Konsole. Sende /nope: eine 404, und in der Konsole wird weiterhin GET /nope angezeigt, weil die Middleware ausgeführt wird, bevor Express nach einer Route sucht.
Probier es selbst
import { escapeHtml } from './html.js';
import express from 'express';
import { recipes } from './data.js';
const app = express();
app.use(express.static('public'));
app.get('/', (req, res) => {
const items = recipes.map((r) => `<li><a href="/recipes/${r.id}">${escapeHtml(r.title)}</a></li>`);
res.send(`<link rel="stylesheet" href="/style.css"><h1>Recipe Box</h1><ul>${items.join('')}</ul>`);
});
// type('text') sendet unformatierten Text, sodass jeder Titel in einer eigenen Zeile erscheint.
app.get('/recipes', (req, res) => {
const { tag } = req.query;
const list = tag ? recipes.filter((recipe) => recipe.tags.includes(tag)) : recipes;
res.type('text').send(list.map((recipe) => recipe.title).join('\n'));
});
app.get('/recipes/:id', (req, res) => {
const recipe = recipes.find((r) => r.id === Number(req.params.id));
if (!recipe) {
res.status(404).send('No such recipe');
return;
}
res.send(recipe.title);
});
app.get('/api/recipes', (req, res) => {
res.json(recipes);
});
app.get('/api/recipes/:id', (req, res) => {
const recipe = recipes.find((r) => r.id === Number(req.params.id));
if (!recipe) {
res.status(404).json({ error: 'No such recipe' });
return;
}
res.json(recipe);
});
app.get('/about', (req, res) => {
res.send('Recipe Box collects family recipes.');
});
app.get('/menu', (req, res) => {
res.redirect(301, '/recipes');
});
app.get('/menu/:id', (req, res) => {
res.redirect(301, `/recipes/${req.params.id}`);
});
app.listen(3000, () => {
console.log('Recipe Box is running on port 3000');
});
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Express-Grundlagen
Übe selbstständig: Express-Playground