Всем привет!
Сегодня со мной произошёл странный случай, даже можно сказать, особенный. Поступило сообщение на странную работу формы. Такое периодически случается, и проблема не всегда в кривых руках юзеров, которым свойственно принимать особенность работы за «страшные ошибки», или менеджерах, у которых «вчера отображалось как-то иначе».
Началось всё с репорта, что после отправки формы она появляется снова, с заполненными полями, но с ошибкой на капче. При этом, письмо с введёнными данными приходит.
Конечно же, сразу проверил. Всё ожидаемо работало как должно, после отправки формы появлялось сообщение о том, что данные приняты.
На мой ответ, что проблем не обнаружено, получил существенное дополнение — трабла появляется в Internet Explorer 11. Уже лучше.
Заполняю форму и отсылаю. Успешно. Странно, но бывает. Жму назад и повторяю «трюк». Баг! Ввожу капчу ещё раз, отправляю — опять выводится страница с предупреждением о неверно разгаданных циферках с картинки.
На почту, тем временем, падает пара писем. Очевидно, что форма работает. Но почему же IE при отправке грузит старую страницу?
По стандарту браузеры обязаны не кешировать POST-запросы.
Вообще, существует не так много возможных проблем. Порой таблица базы покрашится (для MyISAM штатное дело). Ещё встречалось такое, что в ходе копипасты старой формы с небольшими изменениями, появлялась возможность «проскочить» проверку — в старом скрипте использовалась проверка на переменную, которую из нового убрали. Данные по факту не проверяются (нет переменной). Но и ошибок нет, и пришёл POST-запрос. В данном случае, проблемы были не в этом.
Думаю, что если IE чихает на стандарты и кеширует старый запрос, логично посылать заголовки запрета кеширования. Делаю. Проблема остаётся.
Хорошо, копаю глубже. Браузеры могут тоже содержать ошибки. Есть беспроигрышный вариант — добавлять уникальные параметры при каждом запросе. В этом случае клиенты по определению не могут закешировать результат — урлы-то разные. Добавляю необходимый код. Проблема остаётся.
Следующий шаг — «гашу» скрипт при успешной проверке входных данных. Проблема остаётся! Это уже что-то из ряда вон.
Ставлю сниффер. Интересуют, прежде всего, заголовки клиента и сервера.
Качаю используемый ранее Microsoft Network Monitor. Тулза замечательная, но работать отказывается.
В ходе дальнейших поисков попадаются решения с упоротыми ценами по $150+. Среди них нашёл бесплатную версию, установил и… оказалось, что она позволяет просматривать логи, созданные «старшей» версией. Идиотизм, что сказать — нафига нужен сниффер, который не в состоянии перехватывать трафик? Меня бы устроила работа для одной программы, без возможностей сохранения результатов и ещё кучей ограничений. Ну да ладно.
В итоге, нарыл старый добрый Fiddler. Ловит далеко не все пакеты, но что есть…
Смотрю заголовки и тихонько офигеваю — следует запрос, сервер возвращает результат — редирект (так и должно быть), далее браузер осуществляет повторный запрос на адрес валидации формы, передаёт POST-данные (WTF? Как?!!) и, естественно, на страницу вываливается ошибка — после успешного разгадывания данные по старой капче уничтожаются.
Тут я малость подзастрял. Но, как говаривал старина Холмс: «Отбросьте всё невозможное, то, что останется, и будет ответом, каким бы невероятным он ни оказался». Всё, от серверной части до клиентской, работает. Остальные браузеры это подтверждают. Проверено всё, кроме… JavaScript.
Лезу сначала в код формы, листаю до сабмита, и общая картина примерно складывается. Простейший код, без нагромождений:
<form action="" method="post" id="myform">
<!-- здесь поля формы -->
<button type="submit" onclick="document.getElementById('myform').submit()">Отправить</button>
</form>
Конкретно насторожил этот момент:
onclick="document.getElementById('myform').submit()"
Эту штуку верстал не я. Она досталась, как и дизайн, от одной веб-студии. Не ясно, для чего на кнопку, отправляющую форму, нужно вешать код для того же действия.
Проверяю. Удаляю код-огрызок — форма работает как надо. И снова. И ещё раз.
Таким образом, происходило следующее. Firefox и Chrome отправляли форму один раз и успокаивались. Internet Explorer действовал иначе: сначала отправлял форму по событию onclick, и тут же генерировал отправку по стандартному button=submit. Если первый запрос чуть подвисал, второй исполнялся раньше и выдавалось сообщение об успешном принятии данных. Но так случается не всегда, обычно сервер успевает обработать первый запрос раньше, а на следующем (основном) капча не проходит проверку.
На этой радостной ноте всем желаю успехов. Пока-пока.
днём интернета
шоколадкой для работы мозга
коробочкой ароматного чая для бодрости
продлением хостинга на +1 месяц