Pierwsze middleware
Część sekcji Podstawy Express ścieżki Node.js w Coddy. Lekcja 13 z 23.
Niektóre czynności dotyczą każdego żądania, na przykład zapisanie wiersza w dzienniku, a kopiowanie ich do każdej trasy nigdy by się nie skończyło. Każde żądanie ma metodę w req.method: GET, aby pobrać coś, POST, aby coś wysłać.
let visits = 0;
app.use((req, res, next) => {
visits++;
next();
});Funkcja przekazana do app.use to oprogramowanie pośredniczące: Express uruchamia ją dla każdego żądania, w kolejności dodania, przed znajdującymi się niżej trasami. Otrzymuje trzeci argument, next. Wywołanie next() przekazuje żądanie dalej, do kolejnego elementu. Oprogramowanie pośredniczące, które ani nie odpowiada, ani nie wywołuje next(), sprawia, że żądanie czeka bez końca.
express.static z poprzedniego rozdziału również jest oprogramowaniem pośredniczącym: odpowiada, gdy znajdzie plik, a gdy go nie znajdzie, wywołuje next().
Wyzwanie
ŁatwyChcesz, aby serwer zapisywał w dzienniku wiersz dla każdego otrzymanego żądania, żeby widzieć, o co proszą odwiedzający.
- W pliku
server.js, zaraz poconst app = express();, dodaj oprogramowanie pośredniczące za pomocąapp.use. Umieszczone w tym miejscu, będzie uruchamiane przed każdą trasą. - Dla każdego żądania wypisuje w konsoli jeden wiersz: metodę żądania, spację, a następnie jego ścieżkę. Żądanie
/recipes/2wypisujeGET /recipes/2. Metoda znajduje się wreq.method(GET,POSTi tak dalej), a ścieżka wreq.url. - Po wypisaniu wywołuje
next(), dzięki czemu żądanie przechodzi dalej do tras.
Wypróbuj: Naciśnij „Uruchom” i wyślij /recipes/2. Powinien pojawić się wynik Pancakes, a w konsoli GET /recipes/2. Wyślij /api/recipes: jak zwykle pojawi się lista, a w konsoli GET /api/recipes. Wyślij /nope: otrzymasz błąd 404, a w konsoli nadal pojawi się GET /nope, ponieważ oprogramowanie pośredniczące uruchamia się, zanim Express zacznie szukać trasy.
Spróbuj swoich sił
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') wysyła zwykły tekst, więc każdy tytuł pojawia się w osobnym wierszu.
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');
});
Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.
Wszystkie lekcje w sekcji Podstawy Express
Poćwicz samodzielnie: Edytor online Express