Ajax-запросы нативными средствами Joomla

от автора

Небольшая заметка о том, как делать ajax-запросы штатными средствами без использования дополнительных js-библиотек (jQuery, etc). Joomla 3 и Joomla 4 предоставляют небольшую обёртку для конструирования XMLHttpRequest. В целом синтаксис очень похож на тот же jQuery Ajax, поэтому заменить его будет очень легко.

В <head> страницы можно увидеть core.js, в котором есть немало любопытных функций для работы с фронтом на Joomla. Об одной из них (получение данных из php в js) писалось здесь: Разработка форм обратной связи для магазинов на Joomla 3. Для создания ajax-запросов нам пригодится Joomla.request.

Ajax в Joomla — Joomla.request

Joomla 3

Представим, что Вам нужно просто отправить запрос, не получая никаких данных:

Joomla.request({  url: 'index.php?option=com_example&view=example'       })

Выбор метода запроса (POST или GET)

Joomla.request({ url: 'index.php?option=com_example&view=example',       method: 'POST'     })

Если выбран метод запроса POST. то автоматически будет отправляться заголовок X-CSRF-Token и сам CSRF-токен, который можно и нужно проверить в точке входа.

Проверка CSRF-токена в точке входа

Для этого используем метод Session::checkToken. В качестве параметра можно указывать как post (это значение по умолчанию), так и get.

use Joomla\CMS\Session\Session; use Joomla\CMS\Language\Text; Session::checkToken('get') or die(Text::_('JINVALID_TOKEN'));

Проверить наличие CSRF-токена на странице можно в консоли браузера:

Joomla.getOptions в консоли браузера
Joomla.getOptions в консоли браузера

Если CSRF-токена в Joomla Script options нет, то в PHP можно его добавить с помощью класса HTMLHelper.

HTMLHelper::_('form.csrf');

Установка заголовков ajax-запроса

Есть возможность установки своих заголовков ajax-запроса. Например, заголовка Cache-Control, тогда будет корректно работать условная ajax-корзина, каждый раз получая свежие данные. Также можно устанавливать свои уникальные заголовки, если это необходимо.

Joomla.request({   url: 'index.php?option=com_example&view=example',   method: 'POST',   headers: {   'Cache-Control' : 'no-cache',     'Your-custom-header' : 'custom-header-value'   } })

Отправка данных через ajax в Joomla

Отправка данных на выбранный url происходит согласно спецификации. Чаще всего это или строка или объект. Для того, чтобы данные пришли в удобном виде стоит применить к передаваемому объекту JSON.stringify, так же указать заголовок запроса Content-type:applictation/json. Хорошая статья о FormData на learn.javascript.ru в помощь.

Joomla.request({   url: 'index.php?option=com_example&view=example',   method: 'POST',   headers: {           'Cache-Control' : 'no-cache',         'Your-custom-header' : 'custom-header-value',           'Content-Type': 'application/json'       },   data:  JSON.stringify({   'key1' : 'value1',     'key2' : 'value2'   }) })

Если метод запроса POST, в data передается просто строка и не установлен заголовок Content-Type, то он (Content-Type) принимает значение application/x-www-form-urlencoded. В php получаем данные следующим образом:

use Joomla\CMS\Factory; $data = Factory::getApplication()->input->json->getArray();

Callback-функции ajax-запроса в Joomla

  • onBefore: function(xhr){} — выполняется перед запросом. Запрос не выполнится, если данный callback вернёт false.

  • onSuccess: function(response, xhr){} — выполняется после успешного завершения запроса. response — это xhr.responseText,

  • onError: function(xhr){} — выполняется после неудачного запроса.

Joomla.request({      url: 'index.php?option=com_example&view=example',      method: 'POST',      headers: {                'Cache-Control' : 'no-cache',              'Your-custom-header' : 'custom-header-value',     'Content-Type': 'application/json'   },   data:  JSON.stringify({   'key1' : 'value1',     'key2' : 'value2'   }),   onBefore: function (xhr){     // Тут делаем что-то до отправки запроса.      // Если вернём false - запрос не выполнится   },   onSuccess: function (response, xhr){   // Тут делаем что-то с результатами          //Проверяем пришли ли ответы if (response !== ''){ let jshopping_cart = JSON.parse(response);           // И дальше делаем, например, супер-аякс-корзину-под-joomshopping           }    },   onError: function(xhr){   // Тут делаем что-то в случае ошибки запроса.      // Получаем коды ошибок и выводим сообщения о том, что всё грустно.   } })

Запрос обёрнут в try-catch, поэтому если запрос не проходит — смотрим в консоль, там должна логироваться ошибка.

Флаг perform

Это значение по умолчанию установлено в true. Если установить в false — запрос не будет выполняться, а так же не будет вызываться callback-функция onBefore. Полезно в тех случаях, когда не нужно в процессе разработки некоторое время дёргать лишний раз сервер.

Joomla.request({      url: 'index.php?option=com_example&view=example',      method: 'POST',      headers: {                'Cache-Control' : 'no-cache',              'Your-custom-header' : 'custom-header-value',     'Content-Type': 'application/json'   },   data:  JSON.stringify({     'key1' : 'value1',     'key2' : 'value2'   }),   onBefore: function (xhr){     // Тут делаем что-то до отправки запроса.      // Если вернём false - запрос не выполнится   },   onSuccess: function (response, xhr){     // Тут делаем что-то с результатами     //Проверяем пришли ли ответы         if (response !== ''){         let jshopping_cart = JSON.parse(response);             // И дальше делаем, например, супер-аякс-корзину-под-joomshopping           }    },   onError: function(xhr){     // Тут делаем что-то в случае ошибки запроса.      // Получаем коды ошибок и выводим сообщения о том, что всё грустно.   },   perform : false // вся проделанная выше работа бесполезна. Запрос прерван. })

Joomla 4

В Joomla 4 метод переписан, но для простых смертных всё остается так же. Добавляется лишь ещё одна callback-функция onComplete, которая выполняется в любом случае — как после успешного запроса, так и в случае ошибки.

Joomla.request({ url: 'index.php?option=com_example&view=example',   method: 'POST',   headers: {   'Cache-Control' : 'no-cache',     'Your-custom-header' : 'custom-header-value',     'Content-Type': 'application/json'     }, data:  JSON.stringify({     'key1' : 'value1',     'key2' : 'value2'   }),   onBefore: function (xhr){     // Тут делаем что-то до отправки запроса.     // Если вернём false - запрос не выполнится   },   onSuccess: function (response, xhr){     // Тут делаем что-то с результатами     //Проверяем пришли ли ответы     if (response !== ''){     let jshopping_cart = JSON.parse(response);     // И дальше делаем, например, супер-аякс-корзину-под-joomshopping     }   },   onError: function(xhr){     // Тут делаем что-то в случае ошибки запроса.     // Получаем коды ошибок и выводим сообщения о том, что всё грустно.   },   onComplete: function (xhr){     // Тут что-то делаем в любом случае после ajax-запроса.          // в не зависимости от результата.   } });

Приветствую аргументированные замечания и пожелания к заметке.


ссылка на оригинал статьи https://habr.com/ru/articles/588651/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *