Поля с именем и фамилией HTML-формы и пакет «express-validator»

Mar 04, 2022 21:12

Начало:
1. MDN Web Docs: учебник по Express, ч.6-2: форма для создания нового автора
2. Поле даты в HTML-форме и пакет «express-validator»

В первом из предыдущих постов я реализовал страницу динамического сайта (веб-приложения) с HTML-формой для ввода пользователем данных об авторе книг. Веб-приложение построено на базе веб-фреймворка «Express» и работает в рамках среды выполнения «Node.js». Код функции-контроллера и шаблона страницы я взял из руководства по веб-фреймворку «Express» с обучающего сайта «MDN Web Docs».

Во втором из предыдущих постов я нашел причину ошибки с полем даты в HTML-форме и исправил эту ошибку.

В этом посте я буду разбирать причину ошибки с полем для имени и с полем для фамилии автора книг в HTML-форме. Полученный из руководства код функции-контроллера выдает для русских букв в этих полях ошибку «В имени есть не буквенно-цифровые символы.» или «В фамилии есть не буквенно-цифровые символы.».

Для валидации и очистки строковых значений из полей HTML-формы заданный в руководстве код использует пакет «express-validator». В прошлом посте я немного разобрал, как работает этот пакет. Для поля с именем используется следующая цепочка валидации и очистки (для поля с фамилией она аналогична, поэтому далее я буду рассматривать только поле с именем автора):

body('first_name').trim().isLength({ min: 1 }).escape().withMessage('Имя должно быть указано.')
.isAlphanumeric().withMessage('В имени есть не буквенно-цифровые символы.')

Видно, что в этой цепочке используются стандартный очиститель (санитайзер) «trim», стандартный валидатор «isLength», стандартный очиститель «escape» и стандартный валидатор «isAlphanumeric».

Добавочный метод «withMessage» используется для определения сообщения об ошибке, относящегося к идущему перед этим методом в цепочке валидатору.

В принципе, понятно, что нас интересует валидатор «isAlphanumeric», но кратко пробежимся по назначению других методов в цепочке. Санитайзер «trim» удаляет пробельные символы (в число которых обычно входит не только пробел) в начале и в конце строкового значения, введенного пользователем в указанное поле HTML-формы. После этого валидатор «isLength» с параметром «{ min: 1 }» проверяет количество символов во введенном строковом значении. Если это количество меньше указанного (в данном случае - меньше единицы), то выдается ошибка с указанным сообщением «Имя должно быть указано.».

После этой проверки санитайзер «escape» заменяет «опасные» символы их HTML-мнемониками (по-английски «HTML-entity»), в число «опасных» символов обычно входят <, >, &, ', " и /. После этого, наконец, валидатор «isAlphanumeric» проверяет, есть ли во введенном строковом значении символы, которые являются не цифрами и не буквами. Если таковые есть, выдается указанное сообщение об ошибке «В имени есть не буквенно-цифровые символы.».

Почему же валидатор «isAlphanumeric» выдает ошибку, если во введенном пользователем строковом значении присутствуют русские буквы? Дело в том, что этот валидатор работает отдельно по указанной локали (региональная настройка, по-английски «locale»). Конкретная локаль указывается в параметре валидатора. В данном случае локаль не указана, но по умолчанию используется локаль «en-US» (американский английский). Локаль «en-US» в данном случае включает строчные (маленькие) и прописные (большие) буквы латинского алфавита, а также цифры от 0 до 9.

Таким образом, если нам нужно считать правильными только большие и маленькие русские буквы, а также цифры от 0 до 9, то можно прописать валидатор «isAlphanumeric» с соответствующим параметром, вот так:

.isAlphanumeric(['ru-RU']).withMessage('В имени есть не буквенно-цифровые символы.')

Проблема в том, что я хочу дать пользователю возможность вводить строковые значения как на английском языке, так и на русском языке. Но валидатор «isAlphanumeric» не дает возможности использовать одновременно несколько локалей. Также не получится использовать два валидатора с разными локалями поочередно в одной валидационной цепочке (при вводе английских букв ошибку выдаст один валидатор из двух, а при вводе русских букв ошибку выдаст другой валидатор из двух).

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

А что же делать сейчас при разработке нашего учебного веб-приложения? Можно, конечно, попытаться найти другой пакет для валидации и очистки, но я хочу следовать руководству с сайта «MDN Web Docs», а там используется именно пакет «express-validator». Я решил пока что не отказываться от этого пакета. (Тут, видимо, стоит указать версию этого пакета, которую я использую. На данный момент это версия 6.14.0, самая свежая.) Я решил расширить проверку на буквы латинского и русских алфавитов и цифр от 0 до 9, а буквы других алфавитов пока что оставить в стороне, ведь это всего лишь учебное веб-приложение.

Использовать для этого валидатор «isAlphanumeric» затруднительно, хотя некоторые умудряются:

https://stackoverflow.com/questions/55761766/how-to-include-many-locales-while-checking-isalpha-with-validator-js

Я выбрал способ попроще: использовать стандартный валидатор «matches». Этот валидатор позволяет для проверки использовать регулярные выражения. С помощью этого валидатора можно легко заменить валидатор «isAlphanumeric».

Например, вместо следующего:

.isAlphanumeric().withMessage('В имени есть не буквенно-цифровые символы.')
можно написать так (это точный аналог):

.matches(/[a-zA-Z0-9]+$/).withMessage('В имени есть не буквенно-цифровые символы.')

Если валидатор «isAlphanumeric» мы не можем сильно менять, то валидатор «matches» очень гибок. Нужную нам проверку можно сделать так:

.matches(/[а-яА-ЯёЁa-zA-Z0-9]+$/).withMessage('В имени есть не буквенно-цифровые символы.')

Я внес соответствующие изменения в код функции-контроллера. Теперь моя HTML-форма без ошибок принимает в соответствующие поля буквы латинского и русского алфавитов, а также цифры от 0 до 9. Проблема решена.

Инструмент, Образование, Сайтостроение, Программирование

Previous post Next post
Up