Зарегистрируйтесь, чтобы продолжить обучение

Валидация JS: Веб-разработка

В коде ниже данные от пользователей принимаются и сохраняются как есть. То есть мы полагаем, что пользователи вводят данные корректно:

app.post('/users', (req, res) => {
  const {
    name,
    email,
    password,
    passwordConfirmation,
  } = req.body
  const user = {
    name,
    email,
    password,
  }

  state.users.push(user)

  res.redirect('/users')
})

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

Что такое валидация

Получив данные от пользователя, мы должны их проверить. Такая проверка называется валидацией. Валидация включает два основных элемента:

  • Проверка входных данных на корректность — например, заполнены ли обязательные поля или совпадает ли пароль и его подтверждения
  • Проверка возможности выполнить операцию — например, мы не сможем зарегистрировать нового пользователя, если он пытается ввести почту, связанную с уже существующим аккаунтом

Как проверить корректность данных

Проверить корректность введенного пароля можно простым сравнением:

const {
  password,
  passwordConfirmation,
} = req.body

if (password !== passwordConfirmation) {
  // Что-то делаем, если пароли не совпали
}

Что делать дальше? Будет логично, если мы отобразим ту же форму с двумя важными дополнениями:

  • Нужно сохранить введенные данные, чтобы пользователю не пришлось заполнять все поля заново
  • Нужно вывести сообщения об ошибках — например, списком над формой.

В Fastify есть встроенный механизм валидации данных. Дополнительно к нему мы подключим библиотеку yup, которая облегчит задачу:

npm i yup

Посмотрим сразу на готовый код обработчика, а потом разберем его.

app.post('/users', {
  attachValidation: true,
  schema: {
    body: yup.object({
      name: yup.string().min(2, 'Имя должно быть не меньше двух символов'),
      email: yup.string().email(),
      password: yup.string().min(5),
      passwordConfirmation: yup.string().min(5),
    }),
  },
  validatorCompiler: ({ schema, method, url, httpPart }) => (data) => {
    if (data.password !== data.passwordConfirmation) {
      return {
        error: Error('Password confirmation is not equal the password'),
      }
    }
    try {
      const result = schema.validateSync(data)
      return { value: result }
    }
    catch (e) {
      return { error: e }
    }
  },
}, (req, res) => {
  const { name, email, password, passwordConfirmation } = req.body

  if (req.validationError) {
    const data = {
      name, email, password, passwordConfirmation,
      error: req.validationError,
    }

    res.view('src/views/users/new', data)
    return
  }

  const user = {
    name,
    email,
    password,
  }

  state.users.push(user)

  res.redirect('/users')
})

Вторым параметром в метод post() передаются параметры в виде объекта. Для работы валидации нам достаточно три свойства в этом объекте:

  • attachValidation — этот параметр позволяет включить обработчик запроса, если данные не валидны. По умолчанию, если валидация не проходит, ответ на запрос с ошибкой валидации отправляется сразу, наш обработчик не выполняется. Это не всегда нужно. Например, мы хотим отобразить ошибки и повторно отрисовать форму. Для этого мы можем установить этот параметр в значение true
  • schema — здесь мы задаем схему данных. Данные будут сопоставляться схеме, и если где-то будет несоответствие, валидация выдаст ошибку, текст которой можно задать дополнительным параметром. Например, для проверки минимальной длины имени задан текст 'Имя должно быть не меньше двух символов'. Если текст не задать, то yup выведет свой текст ошибки. В примере выше мы указали требования для тела запроса (body). Оно должно содержать несколько полей. Для каждого поля мы описали требования с помощью методов yup. Например, пароль должен быть строкой и содержать как минимум пять символов. Библиотека yup содержит множество различных инструментов для валидации, ознакомиться с ними можно в документации
  • validatorCompiler — здесь формируется функция валидации. В свойстве мы должны указать функцию, которая в свою очередь возвращает функцию валидации. В общем случае нам достаточно вызывать метод валидации validateSync() и перехватить ошибки. Функция валидации должна вернуть объект. Если ошибки найдены, то их нужно поместить в свойство error. Дополнительно мы можем указать любые проверки. На примере выше мы добавили проверку поля подтверждения пароля, что значение равно полю самого пароля. Здесь могут быть любые другие проверки. Например, мы можем проверять существует ли пользователь с такими же данными и многое другое

Следующим шагом нам остается добавить отображение ошибок на форму:

html
  body
    if error
      p= error.message

    form(action = '/users', method = 'post')
      div
        label Имя:
          input(type = 'text', name = 'name', value = name)
      div
        label Email:
          input(type = 'email', name = 'email', value = email, required = true)
      div
        label Пароль:
          input(type = 'password', name = 'password', value = password, required = true)
      div
        label Подтверждение пароля:
          input(type = 'password', name = 'passwordConfirmation', value = passwordConfirmation, required = true)
      input(type = 'submit', value = 'Зарегистрировать')

Фреймворк позволяет гибко настраивать валидацию, создавать различные схемы и переиспользовать их в разных обработчиках, добавлять общую валидацию для всех запросов. В этом уроке мы разобрали базовое использование, но уже его достаточно для решения основных задач.


Самостоятельная работа

  1. Выполните у себя на компьютере все шаги из урока. Модифицируйте форму для добавления нового пользователя и обработчик так, чтобы происходила валидация данных, введенных пользователем
  2. Сделайте то же самое для курсов. При добавлении нового курса должна происходить валидация названия и описания курса. Название курса должно быть не короче 2 символов, а описание должно содержать не менее 10 символов.
  3. Запустите приложение и попробуйте добавлять новые сущности. Проверьте, что при вводе некорректных данных форма остается заполненной и отображаются сообщения об ошибках
  4. Залейте изменения на GitHub

Для полного доступа к курсу нужен базовый план

Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.

Получить доступ
1000
упражнений
2000+
часов теории
3200
тестов

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно

  • 130 курсов, 2000+ часов теории
  • 1000 практических заданий в браузере
  • 360 000 студентов
Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff