Форма входа и автозаполнение хрома
Расскажу об одной особенности автозаполнения браузеров, которая мешает сделать форму входа
О чем речь
Допустим, у нас есть некоторая форма входа, что-нибудь такое:
Если нажать кнопку прямо сейчас, то произойдет отправка формы. Логин и пароль не заданы, поэтому обычно срабатывает стандартная для сервиса валидация, и форма каким-то образом сообщает, что нужно заполнить два поля.
Получится что-то такое:
Большинство сервисов в интернете делает именно так. Я пособирал немного форм входа из разных сервисов. Вот:
Копилка: эти и другие формы входа (21 картинка)
При отправке пустой формы показывается один или два текста об ошибке. Многим может показаться, что это не очень-то вежливо.
Чтобы не вызывать валидацию пустой формы, можно дизеблить кнопку входа до тех пор, пока в обоих полях что-то не будет заполнено. Валидация на пустоту обоих полей просто никогда не будет срабатывать.
Специальный джаваскрипт-код проверяет значения обоих полей, и если в обоих что-то вписано — включает кнопку входа.
Строго говоря, чтобы форма входа работала и у людей с отключенным джаваскриптом, лучше делать так: при загрузке страницы кнопка активна, потом джаваскрипт выключает кнопку, а другой включи́т её обратно, когда поля будут заполнены. Если у пользователя нет джаваскрипта, то кнопка будет включена и он сможет отправить форму.
Кажется, что теперь все хорошо:
В чем проблема
Но здесь суровая реальность вмешивается в дизайн. Если в Хроме сработает автозаполнение, то поля будут заполнены (хром подсветит автозаполненные поля желтым), но кнопка будет заблокирована:
WTF? Что происходит?
Это сработала система безопасности в Хроме. Если включено автоматическое заполнение полей, то Хром заполняет поля, но доступа к их значениям через джаваскрипт не будет. Доступ к значениям полей будет заблокирован до тех пор, пока пользователь явно не повзаимодействует со страницей, например, не кликнет куда-нибудь мышкой. Так они защищаются от кражи данных на плохо сделанных сайтах, где есть XSS-уязвимости.
Вот задача в баг-трекере Хрома: bugs.chromium.org/p/chromium/issues/detail?id=163072.
Причём если пользователь кликнет по заблокированной кнопке входа, то защита сразу отключится, джаваскрипт получит содержимое полей, включит кнопку и она даже успеет нажаться тем же самым кликом! Т. е. форма на самом деле будет работать. Никто только в здравом уме не будет кликать по заблокированной кнопке.
Как можно выкрутиться
Чтобы уйти от проблемы, всегда можно вернуться к тому варианту поведения, который был изначально — не блокировать кнопку и дать её нажимать. Но если так делать не хочется, вот какие варианты есть ещё:
1. Отлавливать автозаполнение поля
На самом деле автозаполненное поле можно отличить от пустых. Если приложение понимает, что срабатывало автозаполнение, то кнопка входа включается, даже если джаваскрипт говорит, что поля логина и пароля пустые.
Большинство способов определения ходят вокруг обработки CSS-свойств поля. Подборка решений есть, например, здесь: stackoverflow.com/questions/11708092/detecting-browser-autofill
Я не настоящий фронтендер, но решение попахивает костылями. Использовать методы, которые для этого не предназначены — лучший способ получить регрессионную ошибку при следующем обновлении Хрома. Использовать такое решение в продакшене не хочется.
2. Дать нажать, но не показывать две красных надписи
Второй способ — не блокировать кнопку, но при этом не показывать два красных сообщения «Дорогой пользователь, нам жаль, что вы не способны справиться с заполнением двух полей». Можно обойтись с отправкой пустой формы более изящно. Например, можно потрясти формой входа, как это делает Цеплин (http://app.zeplin.io).
3. Поменять дизайн так, чтобы защита Хрома отключалась
Третий вариант — переделать дизайн так, чтобы пользователь был вынужден повзаимодействовать со страницей. В этом случае Хром отключит защиту и блокировка-разблокировка формы будет сработать корректно.
Например, на сайте Студии Лебедева вход находится во всплывающем окне, поэтому к тому моменту, как появится форма входа Хром отключит все защиты и автозаполнение не помешает.
Эппл показывает поле пароля только после клика по полю логина, и к этому моменту паранойя браузеров спадает, автозаполнение тоже срабатывает:
Вот такие пироги.
Было бы интересно собрать десяток-другой статей про форму логина, а потом показывать всем, кто говорит — да что тут такого, одну кнопку нарисовать. Ага. Особенность профессии — за самыми простыми вещами кроется куча работы.