Nickolay.info. Javascript. Javascript для проверки данных на стороне клиента - можно ли так делать?

В инете встречается много странных вопросов и ответов на тему взаимодействия клиентских и серверных скриптов. Мне кажется, достаточно придерживаться спецификаций и чётко понимать разницу между серверным и клиентским приложением.

Когда мы из скрипта на PHP пишем код Javascript оператором print или echo, мы просто выводим его в браузер, точно так же, как обычный HTML. "Передать значение из PHP в Javascript" можно только в этом смысле:

print '<script type="text/javascript">var i='.$i.';</script>';

Здесь переменная яваскрипта i получила значение $i переменной серверного сценария. В дальнейшем яваскрипт может использовать или поменять его, но не передать обратно!

Из Javascript в PHP тем более ничего передать нельзя, ведь Javascript полностью выполняется браузером на стороне клиента (серверные расширения, всякие AJAX и JSQuery здесь не рассматриваем).

Одна из наиболее распространённых проблем - функционал сайта, существенно зависящий от включенного Javascript (например, если проверка данных, введённых пользователем в форму, выполняется только яваскриптом, пользователь чуть похитрее просто отключит яваскрипт и отправит всё, что пожелает). Включение альтернативного содержимого в тег <noscript>, выполняемый только тогда, когда Javascript отключён, помогает не всегда. Даже в том случае, если форма при отключённом скрипте просто не выводится. Что мешает, например, загрузить при включённом Javascript полную версию страницы, а затем, отключив его, обойти встроенные проверки?

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

В коде на PHP после тела яваскрипта, особенно если он критичен для функционала сайта, помещается тег <noscript>, куда можно поместить содержимое, выводимое при отключённом яваскрипте.

print '<script type="text/javascript">var i=1;</script>
       <noscript>
       <p>Для работы этой функции нужен включённый в Вашем браузере Javascript. 
       <a href="help.html">Как включить Javascript?</a></p></noscript>';

Подобный код будет нормально работать на "верхнем" уровне кода PHP, вне всех функций, но в функцию выносить его не стоит.

Теперь посмотрим на следующую форму HTML:

<form method="post" name="f1" action="script.php">
 <table border="0" width="90%" align="center">
  <tr>
   <td>Ваше имя:</td>
   <td><input type="text" name="author" size="20" maxlength="40" value=""></td>
  </tr>
  <tr>
   <td>Сообщение:</td>
   <td><textarea name="message" rows="10" cols="72"
        onchange="document.f1.add.disabled=false;"></textarea>
   </td>
  </tr>
  <tr>
   <td>&nbsp;</td>
   <td><input type=submit name=add class=button value="Отправить" 
        disabled onclick="return check();">
   </td>
  </tr>
 </table>
</form>

Представленная схема позволяет, во-первых, по умолчанию отключить активность кнопки отправки (стандартный атрибут disabled), во-вторых, перед отправкой выполняется функция на Javascript с именем check, которая вернёт истину, если данные правильны, и ложь в противном случае. В простейшем случае функция может быть такой:

<script type="text/javascript">
 function checkmail () {
  var r=true;
  var author=trim(document.f1.author.value);
  var message=trim(document.f1.message.value);
  if ((author=='') || (message=='')) r=false;
  if (r==false) window.alert ('Пожалуйста, заполните оба поля данных.');
  return r;
 }
</script>

Если Javascript включён, кнопка отправки будет активирована после выхода фокуса из поля ввода текста message (конечно, этот "выход" фокуса должен быть не на кнопку отправки, а на поле для ввода капчи), в противном случае этого не произойдёт вовсе. Нужно понимать, что если не включать в код атрибут disabled для кнопки отправки и активацию кнопки через Javascript, обойти все наши Javascript-проверки будет элементарно - просто отключив поддержку яваскрипта в браузере! Разумеется, неплохо защитить скрипт на PHP и проверкой того, с какого URL поступают данные, чтобы отсечь возможность обойти нашу "защиту" созданием альтеративной формы где-нибудь на сервере "хакера":

define ("MY_SERVER","www.vasya.ru");
  //...
  list ($formurl,$formparams) = split ('\?',$_SERVER['HTTP_REFERER']);
  $formparts = split ('/',$formurl);
  if ($formparts[2]!==MY_SERVER) {
   //Вывести сообщение об ошибке вида
   //"Сообщение отправлено не с моего сервера, а с ".$formparts[2]."!"
  }

"Защита", конечно, только от спамера и ламера :) Как и другие данные изначально открытого протокола HTTP, свойство $_SERVER['HTTP_REFERER'] нетрудно подделать, было бы желание. Но я и не знаю способа стопроцентной защиты от спама, обычно достаточно отсечь хотя бы большую его часть.

Ну и заметим, что на 2-5% пользователей (статистические данные по многим сайтам), отключающих яваскрипт или пользующихся браузером без его поддержки, мы, при таком подходе, просто "забиваем". Альтернатива - писать трудоёмкие noscript-версии сайтов.

Рейтинг@Mail.ru

вверх гостевая; E-mail