Obsługa błędu 404
Część sekcji Podstawy Express ścieżki Node.js w Coddy. Lekcja 14 z 20.
Express odpowiada na nieznaną ścieżkę własną stroną, Cannot GET /x, która nie pasuje ani do Twojej witryny, ani do API.
app.use((req, res) => {
res.status(404).send('No forecast here. Try /weather/oslo');
});Middleware bez ścieżki uruchamia się dla każdego żądania, które do niego dotrze. Umieść go za wszystkimi trasami i za express.static: żądania, na które odpowiedziały te elementy, nigdy do niego nie dotrą, więc zobaczy tylko te, na które nic nie odpowiedziało. Odpowiada na żądanie, więc nie potrzebuje next.
req.path to ścieżka bez ciągu zapytania, więc req.path.startsWith('/api/') pozwala odróżnić wywołanie API od strony.
Wyzwanie
Łatwy- Ścieżka w
/api/, na którą nic nie odpowiada, zwraca404z{ "error": "Not found" }. - Każda inna ścieżka zwraca stronę HTML
404z komunikatemPage not found.
Wyślij GET /api/nope, otwórz /nope w widoku strony, a następnie wyślij GET /api/recipes/1.
Spróbuj swoich sił
import express from 'express';
import { randomUUID } from 'node:crypto';
import { recipes } from './data.js';
const app = express();
app.use((req, res, next) => {
console.log(`${req.method} ${req.url}`);
next();
});
app.use((req, res, next) => {
res.set('X-Request-Id', randomUUID());
next();
});
app.use(express.json());
app.use(express.static('public'));
const escapeHtml = (text) =>
text
.replaceAll('&', '&')
.replaceAll('<', '<')
.replaceAll('>', '>')
.replaceAll('"', '"');
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ł wyświetla 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.post('/api/recipes', (req, res) => {
const { title, tags } = req.body;
if (!title) {
res.status(400).json({ error: 'A recipe needs a title' });
return;
}
const recipe = { id: recipes.length + 1, title, tags: tags ?? [] };
recipes.push(recipe);
res.status(201).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');
});
Wszystkie lekcje w sekcji Podstawy Express
3Middleware
Twoje pierwsze middleware