Menu
CoddyTech

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().

challenge icon

Wyzwanie

Łatwy

Chcesz, aby serwer zapisywał w dzienniku wiersz dla każdego otrzymanego żądania, żeby widzieć, o co proszą odwiedzający.

  1. W pliku server.js, zaraz po const app = express();, dodaj oprogramowanie pośredniczące za pomocą app.use. Umieszczone w tym miejscu, będzie uruchamiane przed każdą trasą.
  2. Dla każdego żądania wypisuje w konsoli jeden wiersz: metodę żądania, spację, a następnie jego ścieżkę. Żądanie /recipes/2 wypisuje GET /recipes/2. Metoda znajduje się w req.method (GET, POST i tak dalej), a ścieżka w req.url.
  3. 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');
});
quiz iconSprawdź się

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