Программист разрабатывал веб-сервис, и столкнулся с тяжелым выбором: в какой момент валидировать формы, отправляемые на сервер?
Валидация на клиентской стороне (js в браузере) удобна тем, что без отправки данных на сервер можно показать пользователю, что с введенными значениями что-то не так.
Серверная валидация тоже обязательно нужна, чтобы у злонамеренных пользователей не было возможности подделать форму и заставить сервер выполнить некорректный запрос.
Программировать одну и ту же валидацию дважды (на js для браузера и на Perl для сервера) – досадная трата времени, да и две отдельные проверки обязательно разойдутся со временем.
Программист решил изящно обойти эти противоречия, реализовав проверку один раз – на javascript, и используя ее и на клиентской, и на серверной стороне.
Для проверки концепции (вызов js-функций из perl-кода) программист набросал Mojo-приложение
metro.pl
:
И js-ную функцию проверки
metro_validation.js
:
И сделал тестовые запросы:
Проверка определенно что-то проверяла, но определенно не то, что хотел программист. Что же случилось?
В Perl есть операция .
, а в javascript – нет.
Зато в javascript строки конкатенируются с помощью +
.
Для perl’а почти нет разницы между числами и строками, можно пользоваться теми и другими,
не задумываясь, когда происходят неявные преобразования.
Для javascript’а разница есть. Например, операция +
для чисел действует как сложение,
а для строк – как конкатенация.
В нашем веб-приложении параметры в хеше $form
– строки (неудивительно),
и как строки они попадают в js-функцию metro_validate
.
В результате в переменной sum
оказывается не сумма измерений, а их конкатенация,
и результат сравнения получается совсем не тот, что ожидался.
Для решения проблемы можно было бы принудительно нумерифицировать параметры при передаче в js: