Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Формы и перенаправление после POST

Форма — основной способ получить данные от посетителя. Работа с ней в Express состоит из двух маршрутов: GET показывает пустую форму, POST принимает заполненную, сохраняет данные и перенаправляет посетителя на другую страницу.

Маршруты

Добавьте в src/routes/posts.js два адреса. Маршрут /new должен стоять выше /:id, иначе слово new будет принято за номер статьи:

// src/routes/posts.js
router.get('/', postsController.index);
router.get('/new', postsController.create);
router.post('/', postsController.store);
router.get('/:id', postsController.show);

И не забудьте, что в src/app.js уже должна быть подключена express.urlencoded() — без неё req.body будет пустым.

Шаблон формы

Создайте views/posts/new.ejs:

<%- include('../partials/header') %>
 
<h1>Новая статья</h1>
 
<form method="post" action="/posts">
  <label>
    Заголовок
    <input name="title">
  </label>
  <label>
    Текст
    <textarea name="body" rows="8"></textarea>
  </label>
  <button>Опубликовать</button>
</form>
 
<%- include('../partials/footer') %>

Атрибут name у поля становится ключом в req.body: значение поля title придёт в req.body.title.

Обработчики

// src/controllers/postsController.js
export function create(req, res) {
  res.render('posts/new', { title: 'Новая статья' });
}
 
export function store(req, res) {
  const post = {
    id: posts.length + 1,
    title: req.body.title,
    body: req.body.body,
  };
  posts.push(post);
 
  res.redirect(`/posts/${post.id}`);
}

Откройте /posts/new, заполните поля и нажмите «Опубликовать». Браузер перейдёт на страницу новой статьи, а в списке /posts она появится последней.

Ссылка на форму

Добавьте ссылку в views/posts/index.ejs, чтобы до формы можно было дойти со списка:

<a href="/posts/new">Написать статью</a>

Зачем перенаправлять

Можно было бы сразу ответить шаблоном статьи через res.render(). Но тогда в адресной строке остался бы адрес POST-запроса, и при обновлении страницы браузер отправил бы форму ещё раз — статья создалась бы дважды. Перенаправление превращает ответ в обычный GET-запрос, который можно обновлять сколько угодно. Этот приём называют Post/Redirect/Get.

ШагЗапросОтвет
1GET /posts/newСтраница с формой
2POST /postsПеренаправление на /posts/3
3GET /posts/3Страница новой статьи

Частая ошибка

Форма без method="post" отправляет данные методом GET — они окажутся в адресной строке и в req.query, а маршрут router.post() не сработает. Проверьте, что у формы указан method="post", а адрес в action совпадает с адресом маршрута.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.