Menu
CoddyTech

Weiterleitungen

Teil des Abschnitts Express-Grundlagen der Node.js-Journey von Coddy. Lektion 12 von 23.

Seiten ändern sich, und alte Links in Lesezeichen und Suchergebnissen sollten weiterhin zu einem Ziel führen.

app.get('/old-prices', (req, res) => {
    res.redirect(301, '/prices');
});

Eine Weiterleitung antwortet mit einem Status und einem Location-Header, der die neue URL angibt. Der Browser ruft diese URL sofort auf. res.redirect setzt beides.

Der Status gibt an, wie lange die Änderung bestehen bleibt. 301 bedeutet dauerhaft verschoben: Browser und Suchmaschinen merken sich die neue Adresse und fragen die alte nicht mehr ab. 302, der Standardwert, wenn du keinen Status übergibst, bedeutet vorläufig. Daher verwenden sie weiterhin die alte URL.

challenge icon

Aufgabe

Einfach

Die alten Menüseiten wurden endgültig auf die Rezeptseiten verlegt, und alte Lesezeichen sollten weiterhin funktionieren.

  1. Füge in server.js eine Route für /menu hinzu, die mit dem Status 301 zu /recipes weiterleitet. Das bedeutet, dass die Seite endgültig verschoben wurde.
  2. Füge eine Route für /menu/:id hinzu, die mit demselben Status 301 zur Rezeptseite mit derselben ID weiterleitet: /menu/3 führt zu /recipes/3.

Probiere es aus: Drücke auf „Spielen“ und sende /menu/3. Du solltest den Status 301 und einen Location-Header mit dem Wert /recipes/3 sehen. Sende /menu: 301 mit Location /recipes. Sende /menu/42: 301 mit Location /recipes/42. Bei der Weiterleitung wird nicht geprüft, ob Rezept 42 existiert; /recipes/42 antwortet dann selbst mit 404.

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 Klartext, sodass jeder Titel in einer eigenen Zeile steht.
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.listen(3000, () => {
    console.log('Recipe Box is running on port 3000');
});

Alle Lektionen in Express-Grundlagen

Übe selbstständig: Express-Playground