Что лучше делать на стороне клиента или на стороне сервера?
В нашей ситуации мы используем
Большая часть проверок, которые я выполняю, - это проверка данных по мере их ввода пользователями.
Например, я использую событие keypress, чтобы предотвратить появление букв в текстовом поле, установить максимальное количество символов и указать, что число находится в диапазоне.
Я думаю, лучше будет вопрос: есть ли какие-либо преимущества в проверке на стороне сервера по сравнению с клиентом?
Отличные ответы всем. Веб-сайт, который у нас есть, защищен паролем и рассчитан на небольшую базу пользователей (<50). Если они не используют JavaScript, мы пришлем ниндзя. Но если бы мы создавали сайт для всех, я бы согласился провести валидацию с обеих сторон.
Нет надежного способа заблокировать пользователей, отключающих JavaScript. Если пользователь заходит на вашу страницу с включенным JS, а затем отключает его, вы ничего не можете сделать. (Хорошо, вы можете использовать JS для реализации управления отправкой, чтобы он перестал работать в этом сценарии, но это можно обойти, как и все остальное.)



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Да, проверку на стороне клиента всегда можно полностью обойти. Вам нужно сделать и то, и другое: на стороне клиента, чтобы обеспечить лучший пользовательский интерфейс, и на стороне сервера, чтобы быть уверенным, что вводимые вами данные действительно проверены, а не просто предположительно проверены клиентом.
Если вы выполняете легкую проверку, лучше всего делать это на клиенте. Это сэкономит сетевой трафик, что поможет вашему серверу работать лучше. Если это сложная проверка, которая включает в себя извлечение данных из базы данных или чего-то еще, например паролей, то лучше всего сделать это на сервере, где данные могут быть надежно проверены.
То, что вы говорите, - не лучшая идея. Пользователь всегда может обойти проверку на стороне клиента и отправить все, что захочет, в базу данных.
Преимущество проверки на стороне сервера над проверкой на стороне клиента заключается в том, что проверку на стороне клиента можно обойти / изменить:
Вкратце - всегда, всегда проверяйте на стороне сервера, а затем рассматривайте проверку на стороне клиента как дополнительную «дополнительную услугу» для улучшения взаимодействия с конечным пользователем.
Вы всегда должен проверяете на сервере.
Также наличие проверки на клиенте приятно для пользователей, но совершенно небезопасно.
Я просто повторю это, потому что это очень важно:
Always validate on the server
и добавить JavaScript для быстрого реагирования на запросы пользователей.
Как говорили другие, вам следует делать и то, и другое. Вот почему:
Вы хотите сначала проверить ввод на стороне клиента, потому что вы можете указать лучшая обратная связь со средним пользователем. Например, если они введут неверный адрес электронной почты и перейдут к следующему полю, вы можете сразу показать сообщение об ошибке. Таким образом, пользователь может исправить каждое поле до, в котором они отправляют форму.
Если вы выполняете проверку только на сервере, они должны отправить форму, получить сообщение об ошибке и попытаться найти проблему.
(Эту боль можно облегчить, если сервер повторно отобразит форму с заполненным исходным вводом пользователя, но проверка на стороне клиента все еще выполняется быстрее.)
Вы хотите проверить на стороне сервера, потому что вы можете защитить от злоумышленника, который может легко обойти ваш JavaScript и отправить опасный ввод на сервер.
Доверять своему пользовательскому интерфейсу очень опасно. Они не только могут злоупотреблять вашим пользовательским интерфейсом, но и могут вообще не использовать ваш пользовательский интерфейс или даже браузер.. Что, если пользователь вручную редактирует URL-адрес, запускает собственный Javascript или настраивает свои HTTP-запросы с помощью другого инструмента? Что, если они отправят пользовательские HTTP-запросы, например, из curl или из сценария?
(Это не теоретически; например, я работал над поисковой системой путешествий, которая повторно отправляла поиск пользователя во многие партнерские авиалинии, автобусные компании и т. д., отправляя запросы POST, как если бы пользователь заполнил поисковую форму каждой компании, а затем собрал и отсортировал все результаты. Форма JS этих компаний никогда не выполнялась, и для нас было критически важно, чтобы они предоставляли сообщения об ошибках в возвращенном HTML. Конечно, API было бы неплохо, но это было то, что мы должны были сделать.)
Не допускать этого не только наивно с точки зрения безопасности, но и нестандартно: клиенту должно быть разрешено отправлять HTTP любыми способами, которые он пожелает, и вы должны правильно отвечать. Это включает проверку.
Проверка на стороне сервера также важна для совместимость - не у всех пользователей, даже если они используют браузер, будет включен JavaScript.
Есть некоторые проверки, которые не могут быть выполнены должным образом даже в коде серверного приложения и совершенно невозможны в коде на стороне клиента., потому что они зависят от текущего состояния базы данных. Например, «никто другой не зарегистрировал это имя пользователя», или «сообщение в блоге, которое вы комментируете, все еще существует», или «ни одно из существующих резервирований не совпадает с указанными вами датами», или «на балансе вашего аккаунта все еще достаточно средств для оплаты этой покупки. . " Только база данных может надежно проверить данные, которые зависят от связанных данных. Разработчики регулярно облажаться, но PostgreSQL предлагает несколько хороших решений.
С появлением REST единственным преимуществом проверки на стороне клиента является избежание обращения к серверу. Учитывая тот факт, что проверка на стороне клиента должна быть продублирована на сервере, выполнение проверки клиента является очевидным нарушением принципов DRY, которому нельзя даже доверять.
@kidmosey "это очевидное нарушение принципов DRY" Да, это причиняет боль программистам вроде нас. Но представьте себе форму регистрации. Если дублирование информации «адрес электронной почты должен содержать @» в коде клиента означает, что пользователи получают более быструю обратную связь и больше из них подписываются, что приводит к дополнительному доходу в 100 тысяч долларов в год, это более чем окупает дополнительные расходы на обслуживание. СУХОЙ - очень хороший принцип, но это не единственное соображение. Качество кода на самом деле измеряется тем, насколько хорошо он обслуживает пользователей и организацию при анализе затрат и выгод.
«Никто другой не зарегистрировал это имя пользователя», разве эта проверка не возможна на стороне клиента, когда вы используете Ajax?
@ArunRaaj Да, и таким образом вы поймете большинство проблем, но это не на 100% надежно. Если два пользователя заполняют форму одновременно, им обоим может быть сказано, что user1 является доступным именем пользователя. Когда они отправят, они получат одно и то же имя пользователя, если вы не перепроверете серверную часть. И даже проверка кода серверного приложения может иметь ту же проблему: приходят два запроса, первый проверяет базу данных и получает сообщение ОК, второй проверяет базу данных и получает сообщение ОК, первый сохраняется, второй сохраняется. как дубликат. Только ограничение db unique гарантирует уникальность.
@NathanLong спасибо за ответ, я понял. Я хочу знать, как эта функция хорошо работает в Gmail? разве это не проверка на стороне клиента?
@ArunRaaj Я не знаю, как реализован Gmail, но любая система, которая не проверяет уникальность на уровне базы данных, будет иметь дубликаты; нет никакого способа обойти это. Подумайте об этом так: эта проверка - это по сути о текущего состояния базы данных (какие пользователи там). Только база данных знает свое текущее состояние; любой, кто спросил об этом 0,0001 секунды назад, не знает текущего состояния, только состояние по состоянию на 0,0001 секунду назад.
является полезно иметь здесь проверку на стороне клиента, потому что, если кто-то взял желаемое имя пользователя, он, вероятно, взял его вчера или в прошлом году, а не 1 миллисекунду назад, и приятно узнать, что это было сделано, прежде чем вы отправите форму. Но всегда должен быть перепроверен в точный момент вставки новой записи, иначе могут возникнуть дубликаты. Примечание: чем больше у вас трафика, тем больше вероятность того, что два пользователя заявят об одном и том же одновременно. На сайте с низкой посещаемостью этого может никогда не случиться. Но только уникальный индекс обеспечивает, которого не будет.
Натан, я только что прочитал твои правки 2016 года. И вы правильно указали, что проверки должны выполняться из базы данных. но вы знаете, что проверка базы данных на самом деле происходит на стороне сервера, когда вы проверяете имя пользователя, если оно доступно или нет.
@NathanLong Проверка данных, чувствительных к условиям гонки, не так сложна, как звучит в этом предложении. Это сложно сделать правильно, но создать механизм резервирования, который использует синхронизированный ресурс для запроса. Итак, если пользователь вводит «usernameA», проверка уникальности на сервере запрещает множественные одновременные вызовы для проверки уникальности; если он уникален, также зарезервируйте его с помощью временного токена, назначенного клиенту, который также освобождается, если другое имя пользователя проверяется с тем же идентификатором сеанса. Срок действия токена истекает через разумное время. Пример: резерв места в TicketMaster.
@KMX Я пытался отличить что-то надежное, например, уникальное ограничение db, от чего-то ненадежного, например, когда код серверного приложения выполняет SELECT, за которым следует INSERT, что означает, что есть вероятность, что между ними был сделан еще один INSERT. Блокировка таблицы предотвратит это, но уникальное ограничение намного лучше.
@NathanLong На самом деле, есть другой способ обойти это: транзакции базы данных. В любом случае в схеме db должно быть уникальное ограничение, но транзакции решают более широкий спектр уязвимостей состояния гонки.
Я добавлю к этому, что пользователь может вмешиваться в страницу, например. путем изменения элемента управления <select>, чтобы он содержал фиктивные значения. В некоторых браузерах, например в современных версиях Firefox, это очень легко сделать.
Что ж, я все еще нахожу место, чтобы ответить.
В дополнение к ответам Роба и Натана я бы добавил, что проверка на стороне клиента имеет значение. Когда вы применяете валидацию к своим веб-формам, вы должны следовать этим рекомендациям:
Оба типа проверки играют важную роль в своей области, но самая сильная - на стороне сервера. Если вы получаете 10 тыс. Пользователей в один момент времени, то в конечном итоге вы обязательно отфильтруете количество запросов, поступающих на ваш веб-сервер. Если вы обнаружите, что произошла единственная ошибка, например недействительный адрес электронной почты, они снова отправят форму и попросят вашего пользователя исправить ее, что определенно потребует ресурсов вашего сервера и пропускной способности. Так что лучше применить проверку javascript. Если javascript отключен, вам на помощь придет проверка на стороне сервера, и я уверен, что только несколько пользователей могли случайно отключить его, поскольку 99,99% веб-сайтов используют javascript, и он уже включен по умолчанию во всех современных браузерах.
Я видел, как люди вообще пренебрегали защитой от внедрения кода, не говоря уже о том, чтобы делать это только на стороне клиента. И никакая ссылка на внедрение кода не будет полной без ссылки на это: xkcd.com/327 :)
Вы можете выполнить проверку на стороне сервера и отправить обратно объект JSON с результатами проверки для каждого поля, сведя к минимуму клиентский Javascript (просто отображая результаты) и сохраняя удобный интерфейс без необходимости повторяться как на клиенте, так и на сервере.
Удобный? Может быть. Почти мгновенно и маслянисто гладко? Возможно нет.
На стороне клиента следует использовать базовую проверку через Типы ввода HTML5 и атрибуты шаблона, поскольку они используются только для прогрессивных улучшений для лучшего взаимодействия с пользователем (даже если они не поддерживаются в <IE9 и Safari, но мы не полагаемся на них). Но основная проверка должна происходить на стороне сервера ..
«Но основная проверка должна происходить на стороне сервера». Не должно, должно.
JavaScript может быть изменен во время выполнения.
Я предлагаю образец создания структуры проверки на сервере и обмена ею с клиентом.
Вам понадобится отдельная логика проверки на обоих концах, например:
Атрибуты "required" на стороне клиента inputs
field.length > 0 на стороне сервера.
Но использование одной и той же спецификации проверки устранит некоторую избыточность (и ошибки) зеркальной проверки на обоих концах.
Я предлагаю реализовать как клиентскую, так и серверную проверку, это делает проект более безопасным ... Если мне нужно выбрать один, я пойду с проверкой на стороне сервера.
Вы можете найти необходимую информацию здесь https://web.archive.org/web/20131210085944/http://www.webexpertlabs.com/server-side-form-validation-using-regular-expression/
Я наткнулся на интересную ссылку, в которой проводится различие между грубые, систематические, случайные ошибки.
Client-Side validation идеально подходит для предотвращения грубых и случайных ошибок. Обычно максимальная длина текстуры и ввода. Не имитируйте правило проверки на стороне сервера; предоставьте собственное общее правило проверки (например, 200 символов на стороне клиента; n на стороне сервера, продиктованное строгим бизнес-правилом).
Server-side validation идеально подходит для предотвращения систематических ошибок; он будет обеспечивать соблюдение бизнес-правил.
В проекте, в котором я участвую, проверка выполняется на сервере с помощью запросов ajax. На клиенте я соответственно отображаю сообщения об ошибках.
Дополнительная литература: грубые, систематические, случайные ошибки:
https://answers.yahoo.com/question/index?qid=20080918203131AAEt6GO
Проверка данных на стороне клиента может быть полезна для лучшего взаимодействия с пользователем: например, я, пользователь, который неправильно набирает свой адрес электронной почты, не должен ждать, пока его запрос будет обработан удаленным сервером, чтобы узнать об допущенной им опечатке.
Тем не менее, поскольку злоумышленник может обойти проверку на стороне клиента (и может даже не использовать браузер вообще), проверка на стороне сервера требуется, и она должна быть настоящими воротами для защиты вашего бэкэнда от злонамеренных пользователей.
javascript можно отключить