Menu
CoddyTech

Страницы 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> оборачивает каждый элемент. Неэкранированная разметка может изменить страницу или запустить скрипт в браузере посетителя; экранируй каждое название, даже если оно взято из собственного файла данных.

challenge icon

Задание

Легко

На этом шаге открывается подготовленный для курса проект Recipe Box, а не файлы твоего проекта из урока Status Codes (включая server.js). Твоя предыдущая работа остаётся в своём уроке. Прочитай предоставленные файлы, прежде чем редактировать server.js. В этой копии есть маршруты Recipe Box, коды состояния и общий вспомогательный файл html.js.

Главная страница становится настоящей страницей: списком всех рецептов, каждый из которых ведёт ссылкой на собственную страницу.

  1. В server.js импортируй предоставленный вспомогательный файл escapeHtml из ./html.js.
  2. Измени маршрут /, чтобы он отправлял HTML-страницу вместо приветственного текста. На странице должна быть одна ссылка на каждый рецепт, ведущая на страницу этого рецепта и показывающая его название, например, для рецепта 2: <a href="/recipes/2">Pancakes</a>. Подойдёт список: каждая ссылка в элементе <li>, все элементы внутри одного <ul>. Можно начать с заголовка <h1>Recipe Box</h1>.
  3. Пропусти каждое название через escapeHtml, прежде чем добавлять его на страницу. Тогда Fish & Chips попадёт на страницу как Fish &amp; Chips, а браузер покажет Fish & Chips.
  4. Создай элементы с помощью 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');
});
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Основы Express

Потренируйтесь самостоятельно: Песочница Express