В данном посте опишу не столько решение (хотя, оно довольно востребованное), сколько подход к использованию того что есть и без лишних лисапедов. [spoiler] Итак, задача - сделать красивую форму авторизации на AJAX, которая бы без перезагрузки страницы проверяла валидность логина/пароля, выводила ошибки, и авторизовывала.
Сначала я думал оформить это как решение, но в итоге бы получился очередной лисапед - я не встречал еще ни одного проекта, где такого рода компоненты вставали без кастомизации. Поэтому, посидел, подумал, и представляю, на мой взгляд, красивый подход к решению задачи.
За основу берем стандартный шаблон компонента system.auth.form, который я переделал на выпадашку (было даже в каком-то стареньком шаблоне Битрикса это дело).
Правим под свой стиль, кастомизируем как угодно. Чтобы работало. Теперь пришло время вешать аякс. Разумеется, сначала подключаем jquery (я до сих пор не люблю jquery из коробки, так как наши спохватились поздно, и каждый проект уже оброс своими библиотеками jquery, а винегрет из них я не хочу).
Я не вносил никаких изменений в стандартную форму, кроме как окружил ее дивом login-area. Ели она у вас уже кастомизирована, то проверьте наличие атрибута action. Да и по сути все.
Иду по порядку так, как рождалась идея. Итак, сначала я накидал js-код
<sc ript type="text/javascript">
$(docu ment).on('ready', f unction(){
$('#login-area form').submit(f unction(){
var $this = $(this);
var $form = {
action: $this.attr('action'),
post: {'ajax_key':'<?= md5('ajax_'.LICENSE_KEY)?>'}
};
$.each($('input', $this), f unction(){
if ($(this).attr('name').length) {
$form.post[$(this).attr('name')] = $(this).val();
}
});
$.post($form.action, $form.post, f unction(data){
$('input', $this).removeAttr('disabled');
if (data.type == 'error') {
a lert(data.message);
} else {
window.location = wind ow.location;
}
}, 'json');
return false;
});
})
</sc ript>
Что делает код (небольшой урок по jquery заодно, так сказать): 1. Слушаем сабмит формы, и если он происходит, вклиниваемся в него. 2. Создаем переменные для удобства. Об ajax_key я расскажу ниже. 3. Бежим по всем input, и кидаем их в массив для отправки. 4. Собственно, отправляем данные, ответ принимаем как json. Получаем ответ и обрабатываем его. Если ошибки - выводим их, если все ок - рефрешимся сами на себя (мне этого хватило, но вы можете, например, вывести сообщение об успешно авторизации и скрыть форму)
Код написан, но вот как поулчать ответ без лисапедов, лишних скриптов и прочего? Решение пришлось легко и красиво.
Мы шифруем лицензионный ключ и передаем его в форме. И в этом же шаблоне формы авторизации, проверяем этот ключ, и если он есть и верен, то отдаем данные в формате json. Проверка на ключ нужна по одной причине - чтобы "злоумышленник" не получил лишний раз пустую страницу, передав какой-нибудь ?ajax=Y
1. RestartBuffer - так как страница уже начала выполняться (форма же у вас в шаблоне), то надо сбросить буфер. 2. PUBLIC_AJAX_MODE на всякий случай уберем лишний мусор (такой как "отладка страницы" и прочее). 3. Если форма сработала с ошибкой, то отдаем ошибку как json-объект, иначе говорим, что все ок. 4. Выходим.
Есть одна недоработка, которую я не сделал, так как мне не требовалось - не учитывается защищенная авторизация и пароль передается в открытом виде. Я даже не смотрел как это реализуется, поэтому, если кто-то дополнит код на этот случай, включу в пост.
Естественно, по аналогии вы можете реализовать любую форму - регистрации, восстановления пароля, и прочие.
PS: Убирайте лишние пробелы в коде, вставленные парсером.
Все работает за исключение момента, если пользователь успешно логинится, то вижу в консоле, что ajax выполнен успешно и возвращает type => ok, но яваскрипт не срабатывает, даже обычный alert. По сути jquery не выполняет функцию success, в случае когда пользователь залогинивается.
Дмитрий, данный подход имеет огромный минус - рефреш идет со сбросом кеша браузера, то есть картинки и прочее запросится заново. Напрягает. Если библиотека BX подрублена, можно использовать BX.reload(); (если не подрублена, ради редиректа ее включать не имеет смысла конечно же) Ну или посмотрите ее внутренности.
Алексей, к сожалению нет. Я потом доработал скрипт, чтобы при получении ошибки капчи делался редирект на страницу авторизации. Тут скорее вопрос дизайна, в popup не уместишь еще и капчу, некрасиво. Код привести этот не имею возможности. По идее допилить отдачу надо, да JS.
Долганин Антон, а вы не знаете, можно ли сделать перезагрузку компонента аяксом с LocalRedirect()? Встроенный в компонент аякс конфликтует с валидатором формы, пробую через $.ajax({...}); но там в компоненте LocalRedirect возвращает всю html-страницу сайта. т.е. хотелось бы, что бы форма перезагрузилась с параметрами в url типа success=y, но не получатся.
Что если в вызов компонента system.auth.form добавить "AJAX_MODE" => "Y", а в шаблоне у <form убрать атрибут target ? Вроде работает ajax без дописок всяких.
Группы на сайте создаются не только сотрудниками «1С-Битрикс», но и партнерами компании. Поэтому мнения участников групп могут не совпадать с позицией компании «1С-Битрикс».