JavaScript: проверка на стороне клиента и на стороне сервера

179

Что лучше сделать на стороне клиента или на стороне сервера?

В нашей ситуации мы используем

  • JQuery и MVC.
  • Данные JSON для передачи между нашим представлением и контроллером.

Большая часть проверки, которую я делаю, заключается в проверке данных по мере их ввода пользователями. Например, я использую keypressсобытие, чтобы запретить ввод букв в текстовом поле, установить максимальное количество символов и число в диапазоне.

Я думаю, что лучший вопрос был бы: есть ли какие-либо преимущества в выполнении проверки на стороне сервера по сравнению с клиентской?


Круто отвечает всем. Наш веб-сайт защищен паролем и предназначен для небольшой базы пользователей (<50). Если они не используют JavaScript, мы отправим ниндзя. Но если бы мы разрабатывали сайт для всех, я бы согласился провести валидацию с обеих сторон.

Brad8118
источник
2
javascript можно отключить
Энрико Мурру,
Не существует надежного способа заблокировать пользователей, которые отключают JavaScript. Если пользователь заходит на вашу страницу с включенным JS, а затем отключает его, вы ничего не можете сделать. (Хорошо, вы можете использовать JS для реализации контроля отправки, чтобы он перестал работать в этом сценарии, но это можно обойти, как и все остальное.)
Стюарт

Ответы:

347

Как уже говорили другие, вы должны сделать оба. Вот почему:

Сторона клиента

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

Если вы выполняете проверку только на сервере, они должны отправить форму, получить сообщение об ошибке и попытаться найти причину проблемы.

(Эту боль можно облегчить, если сервер повторно выполнит рендеринг формы с заполнением исходного ввода пользователя, но проверка на стороне клиента все еще быстрее.)

Сторона сервера

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

Доверять своему интерфейсу очень опасно. Они могут не только злоупотреблять вашим пользовательским интерфейсом, но и вообще не использовать ваш пользовательский интерфейс или даже браузер . Что если пользователь вручную отредактирует URL-адрес, запустит собственный Javascript или настроит свои HTTP-запросы с помощью другого инструмента? Что, если они отправляют пользовательские HTTP-запросы из curlили из сценария, например?

( Это не теоретически; например, я работал над поисковой системой для путешествий, которая повторно отправляла POSTзапрос пользователя во многие авиакомпании-партнеры, автобусные компании и т. Д., Отправляя запросы, как будто пользователь заполнил форму поиска каждой компании, затем собрал и отсортировал все результаты. Форма этих компаний JS никогда не выполнялась, и для нас было важно, чтобы они предоставляли сообщения об ошибках в возвращенном HTML. Конечно, API был бы хорош, но это было то, что мы должны были сделать. )

Не допускать этого не только наивно с точки зрения безопасности, но и нестандартно: клиенту должно быть разрешено отправлять HTTP любыми способами, и вы должны отвечать правильно. Это включает в себя проверку.

Проверка на стороне сервера также важна для совместимости - не всем пользователям, даже если они используют браузер, будет включен JavaScript.

Приложение - декабрь 2016

Существуют некоторые проверки, которые невозможно выполнить должным образом в коде приложения на стороне сервера, и они абсолютно невозможны в коде на стороне клиента , поскольку они зависят от текущего состояния базы данных. Например, «никто другой не зарегистрировал это имя пользователя», или «сообщение в блоге, которое вы комментируете, все еще существует», или «ни одно из существующих резервирований не перекрывает запрошенные вами даты», или «на балансе вашего счета все еще достаточно средств для покрытия этой покупки» «. Только база данных может надежно проверять данные, которые зависят от связанных данных. Разработчики регулярно облажаются , но PostgreSQL предлагает несколько хороших решений .

Натан Лонг
источник
30
Это должен быть принятый ответ даже спустя 6 лет: P
Джейкоб Маккей
17
Да, я хотел подождать почти 10 лет, чтобы быть уверенным.
Brad8118
2
@kidmosey «это очевидное нарушение принципов СУХОЙ» Да, это означает боль для программистов, таких как мы. Но представьте форму регистрации. Если дублирование информации «адрес электронной почты должен содержать @» в коде клиента означает, что пользователи получают более быструю обратную связь, и большинство из них регистрируются, что приводит к дополнительному доходу в 100 000 долларов в год, что более чем оплачивает дополнительные расходы на обслуживание. СУХОЙ это очень хороший принцип, но это не единственное соображение. Качество кода действительно измеряется тем, насколько хорошо оно обслуживает пользователей и организацию при анализе затрат и выгод.
Натан Лонг
1
@ArunRaaj Да, и вы поймете большинство проблем таким образом, но это не на 100% надежно. Если два пользователя заполняют форму одновременно, им обоим может быть сообщено, что user1это доступное имя пользователя. При отправке они оба получат одно и то же имя пользователя, если вы не перепроверите серверную часть. И даже проверка в коде приложения сервера может иметь ту же проблему: поступают два запроса, первый проверяет базу данных и получает сообщение «ОК», второй проверяет базу данных и получает сообщение «ОК», первый сохраняется, второй сохраняется как дубликат. Только ограничение уникальности БД гарантирует уникальность.
Натан Лонг
1
@NathanLong Проверки данных, чувствительных к условиям гонки, не так уж сложны, как это предложение делает их обоснованными. Это неправильно, но создать механизм резервирования, который использует синхронизированный ресурс для запроса. Поэтому, если пользователь вводит «usernameA», проверка уникальности на сервере запрещает множественные одновременные вызовы для проверки уникальности; если он уникален, также зарезервируйте его временным токеном, назначенным клиенту, который также освобождается, если другое имя пользователя проверяется по тому же идентификатору сеанса. Срок действия токена должен истечь через разумное время. Пример: резервирование места в TicketMaster.
Эласканатор
79

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

Винко Врсалович
источник
43

Я просто собираюсь повторить это, потому что это очень важно:

Всегда проверяйте на сервере

и добавить JavaScript для отзывчивости пользователей.

Тоби хеде
источник
31

Преимущество проверки на стороне сервера перед проверкой на стороне клиента заключается в том, что проверку на стороне клиента можно обойти / манипулировать:

  • Конечный пользователь мог отключить JavaScript
  • Данные могут быть отправлены непосредственно на ваш сервер кем-то, кто даже не использует ваш сайт, с помощью специального приложения, разработанного для этого.
  • Ошибка Javascript на вашей странице (вызванная любым количеством вещей) может привести к выполнению некоторых, но не всех ваших проверок

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

обкрадывать
источник
18

Вы должны всегда проверять на сервере.

Также наличие проверки на клиенте приятно для пользователей, но совершенно небезопасно.

Питер Боутон
источник
9

Ну, я все еще нахожу место для ответа.

В дополнение к ответам Роба и Натана, я хотел бы добавить, что имеет значение проверка на стороне клиента. Когда вы применяете валидации в своих веб-формах, вы должны следовать этим рекомендациям:

Сторона клиента

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

Серверное

  1. Вы НЕ ДОЛЖНЫ полагать, что проверка, успешно выполненная на стороне клиента, на 100% идеальна Неважно, обслуживает ли он менее 50 пользователей. Вы никогда не знаете, кто из ваших пользователей / emplyee превращается в «зло» и совершает какую-то вредную деятельность, зная, что у вас нет надлежащих проверок на месте.
  2. Даже если он идеален с точки зрения проверки адреса электронной почты, телефонных номеров или проверки некоторых допустимых входных данных, он может содержать очень вредные данные. Который должен быть отфильтрован на стороне сервера, независимо от того, является ли он правильным или неправильным.
  3. Если проверка на стороне клиента обойдена, проверка на стороне сервера приходит к вам, чтобы спасти вас от любого потенциального ущерба для обработки на стороне сервера. В последнее время мы уже слышали много историй об SQL-инъекциях и других методах, которые могут применяться для получения некоторых злых преимуществ.

Оба типа проверок играют важную роль в соответствующей области, но самая сильная - на стороне сервера. Если вы получаете 10 тыс. Пользователей в один момент времени, то вам определенно придется отфильтровывать количество запросов, поступающих на ваш веб-сервер. Если вы обнаружите единственную ошибку, такую ​​как неверный адрес электронной почты, тогда они снова отправят форму и попросят вашего пользователя исправить ее, что определенно приведет к потере ресурсов вашего сервера и пропускной способности. Так что лучше применять проверку JavaScript. Если javascript отключен, то проверка на стороне сервера придет на помощь, и я держу пари, что только несколько пользователей могли случайно отключить его, поскольку 99,99% веб-сайтов используют javascript, и он уже включен по умолчанию во всех современных браузерах.

KMX
источник
Я видел, как люди вообще не защищают от внедрения кода, не говоря уже о том, чтобы делать это только на стороне клиента. И никакая ссылка на внедрение кода не будет полной без ссылки на это: xkcd.com/327 :)
Stewart
8

Вы можете выполнить проверку на стороне сервера и отослать обратно объект JSON с результатами проверки для каждого поля, сохранив минимальный Javascript клиента (просто отображая результаты) и по-прежнему имея удобный для пользователя интерфейс без необходимости повторять свои действия как на клиенте, так и на сервере.

Джонатан
источник
3
Удобный? Может быть. Почти мгновенно и маслянисто гладко? Возможно нет.
quadrupleslap
4

Клиентская сторона должна использовать базовую проверку с помощью типов ввода HTML5 и атрибутов шаблона, поскольку они используются только для прогрессивных улучшений для улучшения взаимодействия с пользователем (даже если они не поддерживаются в <IE9 и Safari, но мы не полагаемся на них). Но основная проверка должна происходить на стороне сервера.

adardesign
источник
«Но основная проверка должна происходить на стороне сервера». Не должен, должен.
Стюарт
4

Я предложу внедрить как клиентскую, так и серверную валидацию, это сделает проект более безопасным ... если мне нужно выбрать одну, я пойду с валидацией на стороне сервера.

Вы можете найти соответствующую информацию здесь https://web.archive.org/web/20131210085944/http://www.webexpertlabs.com/server-side-form-validation-using-regular-expression/

Гаурав Вашишт
источник
2

JavaScript может быть изменен во время выполнения.

Я предлагаю шаблон создания структуры проверки на сервере и обмена ею с клиентом.

Вам понадобится отдельная логика проверки на обоих концах, например:

"required"атрибуты на inputsстороне клиента

field.length > 0 на стороне сервера.

Но использование одной и той же спецификации валидации устранит некоторую избыточность (и ошибки) зеркального отображения валидации на обоих концах.

TaylorMac
источник
2

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

Тем не менее, поскольку злоумышленник может обойти проверку на стороне клиента (и может вообще не использовать браузер), проверка на стороне сервера необходима и должна быть реальным средством защиты вашего бэкэнда от гнусных пользователей.

Биллаль Бегерадж
источник
1

Я наткнулся на интересную ссылку, которая делает различие между грубыми, систематическими, случайными ошибками.

Client-Side validationидеально подходит для предотвращения грубых и случайных ошибок. Как правило, максимальная длина для текстуры и ввода. Не имитируйте правило проверки на стороне сервера; укажите собственное общее правило проверки эмпирического правила (например, 200 символов на стороне клиента; nна стороне сервера, продиктованное строгим бизнес-правилом).

Server-side validationидеально подходит для предотвращения систематических ошибок; это обеспечит соблюдение бизнес-правил.

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

Дальнейшее чтение: грубые, систематические, случайные ошибки:

https://answers.yahoo.com/question/index?qid=20080918203131AAEt6GO

Roland
источник
-2

Если вы делаете легкую проверку, лучше всего сделать это на клиенте. Это сэкономит сетевой трафик, который поможет вашему серверу работать лучше. Если это усложняет проверку, которая включает извлечение данных из базы данных или чего-то подобного, например паролей, то лучше всего сделать это на сервере, где данные могут быть надежно проверены.

Том
источник
2
То, что Вы рекламируете, не лучшая идея. Пользователь всегда может обойти проверку на стороне клиента и отправить все, что он хочет, в базу данных.
Кремува,