AJAX

ajax-in-wordpress

Что такое AJAX?

AJAX является аббревиатурой для Asynchronous JavaScript and XML. XML — это формат обмена данными. UX — сокращение для User eXperience (субъективная оценка степени удобства взаимодействия пользователя с сайтом). AJAX является способом интернет-коммуникаций, который позволяет странице в браузере пользователя запрашивать конкретную информацию с сервера и отображать эту новую информацию на этой же странице без необходимости перезагрузки всей страницы. Вы уже можете себе представить, как это улучшает UX.

В то время как XML — это традиционный формат обмена данными, в обмене на самом деле может быть любой удобный формат. При работе с PHP кодом, многие разработчики предпочитают JSON, потому что в этом случае проще взаимодействовать со внутренней структурой данных, созданной из передаваемого потока.

Чтобы увидеть AJAX в действии, перейдите в консоль WordPress и добавьте категорию или метку. Обратите внимание, когда вы нажимаете кнопку Добавить, вид страницы изменяется, но без перезагрузки самой страницы. Не убедил? Проверьте кнопку назад браузера, если бы страница перегрузилась, вы бы увидели два варианта для страницы.

AJAX даже не требуют действий пользователя, чтобы работать. Google Docs автоматически сохраняет ваш документ каждые несколько минут с помощью AJAX без необходимости инициировать процесс сохранения.

Зачем использовать AJAX?

Очевидно, что это улучшает UX. Вместо представления скучных, статических страниц, AJAX позволяет представить динамический, отзывчивый и дружелюбный UX. Пользователи могут получить немедленную обратную связь, что некоторые действия, которые они предприняли были правильны или неправильны. Нет необходимости отправлять всю форму, прежде чем выяснится, что есть ошибка в одном поле. Важные поля могут быть проверены как только данные будут введены. Также по мере ввода могут быть сделаны подсказки для пользователя.

AJAX позволяет значительно уменьшить количество передаваемых и получаемых данных. Происходит обмен только необходимыми данными, вместо контента всей страницы, что происходит при перезагрузке страницы.

В частности, в отношении к WordPress плагинам, AJAX, безусловно, лучший способ инициировать процесс независимо от контента WordPress. Если вы программировали на PHP раньше, скорее всего, вы бы просто сделали ссылку на новую PHP страницу. Пользователь переходя по ссылке инициирует процесс. Проблема здесь в том, что вы не можете получить доступ к функциям WordPress, когда вы создаете ссылку на новую внешнюю PHP страницу. В прошлом, разработчики обращались к функциям WordPress, подключив файл ядра wp-load.php к своей новой PHP странице. Проблема с таким подходом в том, что вы больше не можете знать правильный путь к этому файлу. Архитектура WordPress теперь достаточно гибкая, так что /wp-content/ и файлы вашего плагина могут быть перемещены из своего обычного места на один уровень от корня установки. Вы не можете знать, где находится wp-load.php относительно файлов вашего плагина и вы также не можете знать абсолютный путь к папке установки.

Что вы можете знать, это куда отправлять AJAX-запрос, потому что это определяется в глобальной переменной JavaScript. Ваш PHP скрипт обработчик AJAX на самом деле хук, поэтому все функции WordPress автоматически доступны ему, в отличие от внешнего PHP файла.

Как я могу использовать AJAX?

Если вы новичок в WordPress, но есть опыт использования AJAX в других средах, вам нужно будет переучивать несколько вещей. Метод, которым WordPress реализует AJAX, скорее всего, отличается от того, к которому вы привыкли. Если все является новым для вас, то не проблема. Вы узнаете основы здесь. После того, как вы освоите базовый AJAX-обмен, можно без проблем расшириться на этой основе разрабатывать прекрасные веб-приложения с удивительным UX!

Есть два основные компонента любого обмена AJAX в WordPress. JavaScript или jQuery на стороне клиента и PHP на стороне сервера. Все AJAX-обмены следуют такой последовательности событий:

  1. Какой-то тип события на странице инициирует функцию JavaScript или jQuery. Эта функция собирает некоторые данные из страницы и отправляет их посредством HTTP запроса на сервер. Так как управление HTTP запросами с помощью JavaScript неудобно и так как jQuery идет в комплекте с WordPress, то с этого момента мы собираемся сосредоточиться только на jQuery коде. Управление AJAX возможно и напрямую с помощью JavaScript, но этого не стоит делать, поскольку доступен jQuery.
  2. Сервер получает запрос и делает что-то с данными. Может, например, собрать соответствующие данные и отправить их обратно в браузер клиента в виде ответа HTTP. Это делать не обязательно, но желательно держать пользователя в курсе о том, что происходит и очень редко, когда не отправляется какой-то ответ.
  3. Функция jQuery, которая отправила начальный AJAX-запрос получает ответ от сервера и делает что-то с ним. Это может что-то обновить на странице и/или представить сообщение пользователю каким-то способом.

Использование AJAX с jQuery

Теперь мы определим часть «делать что-то» из фрагмента в статьи о jQuery. Мы будем использовать $.post() метод, который принимает 3 параметра: URL для отправки POST-запроса, данные для передачи, и функцию обратного вызова для обработки ответа сервера. Прежде, чем мы это сделаем, проведем немного заблаговременного планирования. Мы делаем следующее присваивание для последующего использования в функции обратного вызова. Цель будет более понятна в разделе callback (функция обратного вызова).

URL

Все запросы WordPress AJAX должны быть направлены на wp-admin/admin-ajax.php. Правильный, полный URL должен исходить от PHP, jQuery не может определить это значение самостоятельно, и Вы не можете жестко привязывать URL в коде jQuery и ожидать чтобы кто-либо еще использовал ваш плагин на своем сайте. Если страница из консоли, то WordPress устанавливает правильный URL в глобальной JavaScript переменной ajaxurl. Для общедоступных страниц, вам нужно будет установить соответствующий URL самостоятельно и передать его в jQuery, используя wp_localize_script(). Это будет рассмотрено более подробно в следующем разделе руководства «PHP и отправка в очередь». Сейчас просто знайте, что URL, который будет работать для frontend и backend сайта доступен как свойство глобального объекта, который вы будете определять в PHP части. В jQuery на него ссылаются так:

Данные

Все данные, которые должны быть отправлены на сервер включены в массив данных. Кроме каких-либо данных, необходимых вашему приложению, вы должны отправить параметр действия (action). Для запросов, которые могут привести к изменению базы данных, необходимо отправить одноразовое число, так что сервер узнает, запрос пришел из правильного источника. Пример массива с данными, подаваемых на .post() метод выглядит следующим образом:

Все компоненты описываются ниже.

Одноразовое число (Nonce)

Nonce происходит от английского «Number used ONCE» (число, использующееся 1 раз или одноразовое число). По существу, это уникальный шестнадцатеричный номер, присвоенный каждому экземпляру в любой обрабатываемой форме. Одноразовое число устанавливается с помощью PHP скрипта и передается в jQuery тем же способом, как и URL, т.е. как свойство в глобальном объекте. В этом случае на него ссылаются как my_ajax_obj.nonce

Примечание: настоящее одноразовое число нужно обновить каждый раз, когда оно используется, так что следующий вызов AJAX имеет новое, неиспользованное одноразовое число для отправки в проверке. После того как это происходит, одноразовое WordPress число больше не является одноразовым. Тот же nonce может быть использован столько раз, сколько необходимо в течение 24 часов. Создание одноразового числа с той же посеянной фразы всегда будет давать тот же номер для 12-часового периода, после чего новый номер будет наконец сгенерирован.

Если ваше приложение нуждается в серьезной безопасности, реализуйте истинную систему одноразовых чисел, где сервер посылает новое, свежее одноразовое число в ответ на запрос AJAX для скрипта, чтобы использовать его в следующем запросе.

Проще всего, если вы привяжите это одноразовое значение к _ajax_nonce. Вы можете использовать другой ключ, если он согласован с кодом PHP, подтверждающим одноразовое число, но легче всего использовать значение по умолчанию и не беспокоиться о координации. Вот как появится объявление этой пары ключ-значение:

Действие (action)

Все запросы WordPress AJAX должны включать аргумент action в данных. Это значение является произвольной строкой, которая используется в части построения action тега, который вы используете для хука вашего кода обработчика AJAX. Обычно это значение будет очень краткое описание цели вызова AJAX. Неудивительно, что ключ к этому значению является «action«. В этом примере, мы будем использовать «my_tag_count«, как наше значение действия. Декларация этой пары ключ-значение выглядит следующим образом:

Любые другие данные, необходимые серверу, чтобы выполнить свою задачу, также входят в этот массив. Если есть много полей для передачи, есть два распространенных формата, чтобы объединить поля данных в одну строку для более удобной передачи, XML и JSON. Использование этих форматов опционально, но все, что вы делаете необходимо согласовывать с PHP скриптом на стороне сервера. Более подробная информация об этих форматах доступна в следующей секции — «callback». Более привычным является получение данных в этом формате, чем отправление, но это может работать в обоих направлениях.

В нашем примере, серверу необходимо только одно значение, одна строка для выбранного названия книги, поэтому мы будем использовать ключ ‘title‘. В jQuery, объект, который запустил событие всегда содержится в переменной this. Соответственно, значение выбранного элемента будет this.value. Наше объявление этой пары ключ-значение будет выглядеть примерно так:

Обратный вызов (callback)

Callback обработчик — это функция, которая выполняется, когда приходит ответ от сервера после запроса. Еще раз, мы обычно видим здесь анонимную функцию. Функция принимает один параметр, ответ сервера. Ответом может быть что угодно, от «yes» или «no» до огромной базы данных XML. Данные в формате JSON, также являются полезным форматом для данных. Ответ даже не требуется. Если ответа не существует, то не нужно задавать функцию обратного вызова. В интересах UX, хорошей идеей будет позволение пользователю знать, что случилось на любой запрос, поэтому рекомендуется всегда реагировать и дать некоторое представление пользователю, что что-то случилось.

В нашем примере, мы заменим текущий текст возле радио-кнопки ответом сервера, который включает в себя ряд записей, помеченных соответствующим названием книги. Вот наша анонимная функция обратного вызова:

data содержит весь ответ сервера. Ранее мы назначили this2 объект, который вызвал событие изменения (обозначаемое как this) с помощью строки var this2 = this;. Это потому что область видимости переменных в замыканиях распространяется только на один уровень. Назначая this2 в обработчике событий (часть, которая первоначально только содержала «/* делать что-то */«), мы можем использовать его в функции обратного вызова, где this было бы вне области видимости.

Ответ сервера может принимать любую форму. Значительные количества данных должны быть закодированы в поток данных для облегчения обработки. XML и JSON две распространенные схемы кодирования.

XML

XML является классическим форматом обмена данными для AJAX. Это ведь тот самый ‘X’ в аббревиатуре AJAX. Он продолжает быть жизнеспособным форматом обмена, хотя с ним может быть трудно работать с помощью встроенных функций PHP. Многие PHP программисты предпочитают формат JSON по этой причине. Если вы используете XML, метод синтаксического анализа зависит от используемого браузера. Используйте Microsoft.XMLDOM ActiveX для Internet Explorer и DomParser для всех остальных браузеров.

JSON

JSON часто является предпочтительным из-за его легкого веса и простоты использования. Вы действительно можете разобрать JSON с помощью eval(), но не делайте этого! Использование PHP функции eval() привносит значительные риски для безопасности. Вместо этого, используйте специальный парсер, который к тому же быстрее. Используйте глобальный экземпляр объекта JSON. Убедитесь, что он поставлен в очередь с другими скриптами на странице. Более подробная информация о поставке в очередь в следующей главе этого руководства о PHP.

Другие форматы

Так как формат данных координируется с обработчиком PHP, это может быть любой формат, который вы любите, как разделенный запятыми, разделенный табуляцией, или какой-либо другой структуры, которая работает для вас.

Итог по клиентской стороне

Теперь, когда мы добавили наш обратный вызов в качестве конечного параметра для $.post() функции, мы завершили наш образец jQuery AJAX скрипта. Все части вместе взятые выглядят следующим образом:

Этот скрипт может быть выведен либо в «block» на странице или содержаться в своем собственном файле. Этот файл может находиться в любом месте в Интернете, но большинство разработчиков плагинов помещают его в /js/ подпапке главной папки плагина. Если у вас нет причин поступить иначе, вы можете также следовать такой практике. Для этого примера мы будем использовать имя для нашего файла myjquery.js

Навигация по разделам:

3 комментария

  1. Art

    Доброго.
    Я пытаюсь сделать некий аналог «афоризма дня». У меня есть div text_here, куда хочу выводить текст и две кнопки «обновить» и «новое».

    Если обновить — то новый афоризм этого же автора, если «новый» — то новый айди автора и его новый афоризм.
    Соответственно, алгоритм:

    1. При открытии страницы — получить id и потом по нему вызывать функцию l_mrand_get()
    2. Если юзер нажал «обновить» — с тем же самым id вызывать функцию l_mrand_get()
    3. Если юзер нажал «новый» или обновил страницу — тоже самое, что в пункте 1.

    Что я умею:

    1. Зарегистрировать плагин.
    2. Зарегистрировать шорткат.
    add_shortcode(‘show_phrase’, ‘l_show_phrase’); #

    3.
    # регистрация скриптов аджакса для получения рандомного id — два варианта, для зарегистрированных и нерегистрированных (wp_ajax_nopriv) юзеров.

    if (!is_admin() ) # если я не нахожусь в админке.
    {
    add_action('wp_ajax_get_l_rangom_id', 'l_id_get');
    add_action('wp_ajax_nopriv_l_rangom_id', 'l_id_get');
    add_action('wp_ajax_get_l_rangom_id', 'l_mrand_get');
    add_action('wp_ajax_nopriv_l_rangom_id', 'l_mrand_get');
    }

    3. Умею вызвать процедуры из базы. Передать из них значение вызывателю. База, к которой обращаюсь, у меня не стандартная, не wordpress.

    {
    function l_id_get() # назначается глобальный айди. Его потом можно либо еще раз получить новый, вызвав эту функцию, либо просто пользоваться уже полученным после одного вызова.
    global $m_wpdb;
    $m_id = $m_wpdb->get_var($m_wpdb->prepare("call p_val_get;"));
    header("Content-type: application/json; charset=UTF-8");
    exit(json_encode($m_id)); # передача значения вызывателю
    }
    #
    function l_mrand_get($m_id) # получаю текст по id
    {
    global $m_wpdb;
    $m_text = $m_wpdb->get_var($m_wpdb->prepare("call p_mrand_get ($m_id);"));
    header("Content-type: application/json; charset=UTF-8");
    exit(json_encode($m_text)); # передача значения вызывателю
    }

    Вот такой функцией я рисую текст и кнопки

    function l_show_phrase($content=null)
    {
    if( !is_admin() )
    {
    $content .= "Text here ";
    $content .= " "; # тут делаю две кнопки
    return $content;
    }
    }

    Вот так я узнаю, где лежит
    # Получу url-адрес файла admin-ajax.php с помощью admin_url()
    ajax_url = admin_url('admin-ajax.php');

    Вот так я указываю, где лежит скрипт для обработки нажатий кнопок.

    add_action('wp_enqueue_script','register_my_scripts');
    function register_my_scripts(){
    wp_enqueue_script('jquery');
    wp_enqueue_script('m_ajax_work', plugin_dir_url(__FILE__) . '/js/m_work.js', 1,true );
    }

    Никак не могу сообразить, как нажатием кнопки вызвать функции из m_work.js. :(( Застрял и туплю.

    Функции jquery должны вызвать мои функции на php: l_id_get() and l_mrand_get
    и потом присвоить <div class='text_here' значение, полученное из l_mrand_get

    Т.е. в m_work.js пишу нечто такое:

    # для обновления данных

    function qj_l_refresh(id - тут передать переменную id ) {
    $('button#m_refresh').click(function() {
    $('div#text_here').load('вызвать как-то фунцию php l_mrand_get ');
    });
    }

    # для получения полностью новых данных
    function qj_l_get_new() {
    $('button#'m_get_new').click(function() {
    $('div#text_here').load('вызвать как-то фунцию php l_id_get() и потом l_mrand_get ');
    });
    }

    Уважаемый Евгений. Не дайте пропасть, научите, как сделать два вызова этих!

    Ответить
    • Eugene Kopich

      Привет. Сейчас времени нет, возможно позже гляну
      P.S. вижу на тостере какое продвижение есть, особо не помогу, сам ajax редко использую. Перед тем, как что-то сделать, тоже приходится перечитывать документацию постоянно, в голове весь вагон не удержать)

      Ответить
  2. Art

    Да в общем-то сделал, работает. Единственно что — если не сильно обломно, готовый результат показать бы знающему человеку, критику послушать?

    Чего точно нет — никак не пойму, как не только проверить ошибку, но и не подключить плагин, если скажем, SHow tables like ‘%my_cool_table%’ вернуло null.

    И ясности с оформлением, т.е. подключением css. Но там вроде копейки.

    Ответить

Оставить комментарий

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