Страницы HTML
Часть раздела Основы Express путешествия по Node.js на Coddy. Урок 10 из 23.
Теперь Recipe Box превращает упражнения со строками HTML и экранированием в страницу. Создай по одной ссылке для каждого рецепта. Атрибут href ссылки задаёт её назначение, а текст между тегами — подпись, которую видит читатель.
const link = `<a href="/books/${book.id}">${escapeHtml(book.title)}</a>`;Вспомогательная функция находится в html.js. Применяй её к каждому названию, оставляя собственные теги ссылок в разметке. Используй map, чтобы создать ссылки, а затем join, чтобы объединить их в одну строку. Если передать массив напрямую в шаблонную строку, между ссылками появятся запятые. res.send отправляет готовую страницу браузеру.
<ul> содержит список, а <li> оборачивает каждый элемент. Неэкранированная разметка может изменить страницу или запустить скрипт в браузере посетителя; экранируй каждое название, даже если оно взято из собственного файла данных.
Задание
ЛегкоНа этом шаге открывается подготовленный для курса проект Recipe Box, а не файлы твоего проекта из урока Status Codes (включая server.js). Твоя предыдущая работа остаётся в своём уроке. Прочитай предоставленные файлы, прежде чем редактировать server.js. В этой копии есть маршруты Recipe Box, коды состояния и общий вспомогательный файл html.js.
Главная страница становится настоящей страницей: списком всех рецептов, каждый из которых ведёт ссылкой на собственную страницу.
- В
server.jsимпортируй предоставленный вспомогательный файлescapeHtmlиз./html.js. - Измени маршрут
/, чтобы он отправлял HTML-страницу вместо приветственного текста. На странице должна быть одна ссылка на каждый рецепт, ведущая на страницу этого рецепта и показывающая его название, например, для рецепта 2:<a href="/recipes/2">Pancakes</a>. Подойдёт список: каждая ссылка в элементе<li>, все элементы внутри одного<ul>. Можно начать с заголовка<h1>Recipe Box</h1>. - Пропусти каждое название через
escapeHtml, прежде чем добавлять его на страницу. Тогда Fish & Chips попадёт на страницу какFish & Chips, а браузер покажет Fish & Chips. - Создай элементы с помощью
mapи объедини их пустой строкой. Если вставить массив в шаблонную строку как есть, между элементами появятся запятые.
Попробуй: нажми «Играть» и отправь запрос к /. Ответ отобразится как страница с четырьмя ссылками. Нажми Fish & Chips: откроется страница /recipes/4 с названием Fish & Chips.
Попробуйте сами
import express from 'express';
import { recipes } from './data.js';
const app = express();
app.get('/', (req, res) => {
res.send('Welcome to Recipe Box');
});
// type('text') отправляет обычный текст, поэтому каждое название отображается на отдельной строке.
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');
});
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Основы Express
Потренируйтесь самостоятельно: Песочница Express