Wp ajax


Проводил опрос в своём телеграм канале относительно этого поста и выяснилсь, что большинству он всё-таки нужен, поэтому погнали.

Тут я буду рассчитывать на то, что вы базово знаете PHP, базово знаете jQuery. Если да, то трудностей этот урок вызвать не должен.

Если вы не знаете этих вещей, то сорян, вам тут вычитывать нечего. ? Заглядывайте чуть попозже.

Если вы не уверены в своих силах, сначала просто неспеша вчитайтесь в эту статью, а только потом приступайте к действию. Всё у вас получится ?

Тут важно уточнить, что это именно урок для начинающих, тут мы не будем работать с типами данных json, выполнять nonce-проверки и пр.

0. Подготовка 

Как я уже говорил, я предполагаю, что вы базово знаете jQuery, поэтому подобная конструкция для вас ясна как день ?

На всякий случай напомню, что должна быть подключена библиотека jQuery, а упомянутый выше код находиться после нее, сразу покажу, ок?

Если применять это к правильному подключению JavaScript в WordPress, то в теме это вполне может выглядеть так:

То есть библиотека jQuery уже была подключена через wp_enqueue_script() либо в wp_head(), либо в wp_footer(), наша же задача закинуть наш собственный код jQuery после неё. Знаю, что мы можем сделать это через файл, мы можем сделать это через хук, а можно и просто в шаблоне вывести (у вас это возможно footer.php


будет, но не факт).

В этом уроке для простоты понимания весь мой jQuery код будет находиться в файле footer.php темы.

Итак, прежде, чем переходить к следующему шагу, добейтесь вот этого ?

1. Познакомимся с $.ajax 

В jQuery есть несколько способов отправки асинхронных запросов, сам я пользуюсь только $.ajax, так как он более универсален, остальные – лишь частные случаи из него. В общих чертах, учитывая всё необходимое, код будет выглядеть вот так?

Го по строчкам прокомментирую:

  • 4 – абсолютный URL обработчика PHP, то есть ссылка на файл, например https://misha.blog/myajax.php
  • 5 – точно так же, как и с отправкой форм, если используете POST, то для получения переменных в PHP вам нужен массив $_POST, если используете GET, то тогда будете использовать массив $_GET
  • 6 – сами параметры, тут я их передал в виде урл-строки, но вы можете передавать их также в виде объекта, для объекта это будет выглядеть так:

    И соответственно, вне зависимости от того, какой вариант указания параметров вы выберете, для нашего примера они будут доступны в PHP коде (я решил назвать файл myajax.php, помним да?) при помощи $_POST['param1'] и $_POST['param2'].


  • 7-9 – это функция, которая выполнится перед отправкой запроса, тут можно годно активировать всякие прелоадеры, я вот например изменил текст кнопки .
  • 11-14 – это функция запускается сразу после получения данных, а данные это… параметр этой функции конечно же, он может называться по-разному, у меня — data
  • У функции $.ajax есть много прикольных параметров, я рекомендую попрактиковаться с ними, документацию можете найти на официальном сайте.

Так, теперь самая важная часть – обработка запроса в PHP. У нас с вами есть файл myajax.php, который находится в корне сайта, пусть он сложит два параметра – param1 и param2 и возвратит нам их сумму. Ну изи же? ?

Прежде, чем перейти к следующему шагу, сделайте, чтобы при нажатии на кнопку у вас выводилась сумма двух параметров в alert().

Почему мы складываем числа в PHP, когда это можно сделать непосредственно в JavaScript на стороне клиента? Потому что мы учимся, Карл! Если слишком легко для тебя, отправляйся в пост посложнее или ещё сложнее.

2. Познакомимся со стандартным обработчиком асинронных запросов в WordPress – admin-ajax.php 

Сам код отправки асинхронного запроса изменится совсем чуть-чуть:


  • На 4й строчке мы указываем на путь на наш собственный файл-обработчик, а на стандартный вордпрессовский, он всегда находится в одном месте — https://misha.blog/wp-admin/admin-ajax.php (только домен моего сайта замените на свой, очень прошу). Так как я использую мой код в файле footer.php, в среде WordPress, то я могу получить путь к этому файлу динамически, например при помощи функции admin_url() или site_url().
  • На 6-й строке, там где передаются параметры, обязательно нужно указать параметр action с каким-нибудь произвольным значением, которое мы будем подцеплять чуть позже.

И вторым шагом нужно будет создать функцию в functions.php и повесить её на два хука (если используете AJAX в админке, то только на один кстати).

3. Распространённые косяки 

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

Ничего не происходит или страница перезагружается ?

Скорее всего у вас синтаксическая ошибка в вашем JavaScript-коде, для этого мы открываем консоль браузера и смотрим, где она примерно находится и на что похожа, например:

То есть уже примерно понимаем, что к чему.

Выводится 0 вместо того, что я хочу ?

Я вас поздравляю ? — если вывелся 0, значит с вашим кодом jQuery всё прекрасно! Обычно 0 означает, что запрос к admin-ajax.php


выполнился, но произошло несоответствие параметра action.

То есть в запросы вы передали одно его значение (или не передали вовсе), а в хуках wp_ajax_ и wp_ajax_nopriv_ указали другое (либо использовали не по назначению лишь один из хуков).

Асинхронный запрос выполняется, но вообще ничего не выводит ?

Скорее всего ошибка в PHP-коде вашего обработчика PHP, если он — это функция в functions.php, то это вряд ли пропущенная точка с запятой (тогда бы полетел весь сайт), скорее всего это просто несуществующая функция или класс.

В консоли браузера в таких случаях ошибка 500.

misha.blog

AJAX — очень крутая штука. Эта штука позволяет создавать действительно классные интерактивные приложения. Грубо говоря, с помощью AJAX можно делать разные привычные вещи “без перезагрузки страницы”: подгрузка новых статей без перезагрузки страницы, отправка комментариев WordPress без перезагрузки страницы, вывод результатов поиска под полем ввода без перезагрузки страницы.


AJAX в WordPress

По возможности, буду стараться создавать новые проекты с использованием AJAX. Это действительно очень удобно. Пользователю не нужно сидеть и смотреть на белый экран браузера, пока загрузится сайт — можно добавить красивенький прелоадер, прогресс-бар или надпись “Подождите секундочку…”. Тот же VK работает на AJAX. Ладно, не буду расписывать много об этом (это тема отдельной статьи), думаю, суть ясна.

AJAX — подход к построению интерактивных пользовательских интерфейсов веб-приложений, заключающийся в «фоновом» обмене данными браузера с веб-сервером. В результате, при обновлении данных веб-страница не перезагружается полностью, и веб-приложения становятся быстрее и удобнее.

Википедия

А теперь ближе к теме. У WordPress есть очень удобный функционал для работы с AJAX. Достаточно написать нужную нам функцию и вызвать ее через ajax-хук.

Выглядит он таким образом:

Где myaction — имя нашего хука, а action_handler — имя функции, которую он вызывает. Стоит отметить, что этот хук сработает только для авторизованных пользователей. В этом есть смысл, когда мы пишем что-то для админки, но чтобы он работал для всех посетителей сайта, нужно продублировать хук с добавленным словом nopriv, то есть в полном виде будет так:

Для отправки самих же AJAX запросов я использую встроенную функциональность в jQuery.

Да, в url должен стоять адрес /wp-admin/admin-ajax.php

Пример

Я написал новый пост с обновленным примером. Там более актуальный код и лучше разжевано. Вот ссылка.


Где-то в феврале я делал вот такой блог http://blogstark.ru/ (видно, сайта уже нет). Несмотря на его типичность, функциональность в нем не совсем типичная:)

AJAX здесь используется в двух случаях: подсчетов количества просмотров страниц (и его отображение) и подсчет кол-ва лайков, точнее репостов статьи (реальных, а не кликов по кнопкам). О втором случае расскажу уже в следующей статье, а кол-во просмотров покажу здесь.

И так, сначала пишем две функции в functions.php для подсчета и вывода количества просмотров статьи.

В первом случае получаем статью по её id, добавляем единицу к просмотру и пишем значение в базу, во втором — читаем значение.

Теперь немного JavaScript.

Создаем две функции, которые принимают id поста.

postviewCountGet получает из базы кол-во просмотров статьи, а postviewCountSet добавляет +1 к просмотру статьи.

Использовать AJAX в WordPress для подсчета количества просмотров — идеально. Во-первых, это решает проблему с кэшированием. На сайте используется мой любимый Hyper Cache, с этим нет никакой головной боли. Во-вторых, за счет этого сама страница загружается быстрее, так как ее можно достать из кэша, начать читать, а потом уже асинхронно подгрузятся циферки.


Для защиты/проверки запросов можно использовать nonce (wp_create_nonce(),wp_verify_nonce()).

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

popovses.net

AJAX-обработчик на бекенде

Некоторые люди делают AJAX-обработчик вручную, путем инклюда файла wp_load. Это считается очень и очень плохой практикой по целой куче причин. У WordPress есть свой, готовый обработчик. Будьте паиньками и пользуйтесь им.

После того, как фронтенд «узнал», куда ему слать запросы, нужно добавить на бекенде хук для обработки этих запросов. Обязательный параметр в этих запросах — action: этот параметр определяет, что именно мы "хотим" от бекенда.

Для того, чтобы создать новый метод AJAX-обработчика, нужно повесить два хука: wp_ajax_<имя экшена> и wp_ajax_nopriv_<имя экшена>. Например, вот так:

add_action('wp_ajax_get_posts' , 'get_posts_callback'); add_action('wp_ajax_nopriv_get_posts', 'get_posts_callback');   

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

Эти хуки — самые обычные, такие же, как все остальные WP-хуки. В результате регистрации таких хуков при обращении к УРЛ-у wp-admin/admin-ajax.php?action=get_posts должна выполниться функция get_posts_callback.

add_action( 'wp_ajax_do_something', 'get_posts_callback' ); // For logged in users add_action( 'wp_ajax_nopriv_do_something', 'get_posts_callback' ); // For anonymous users  function do_something_callback(){  echo(json_encode( array('status'=>'ok','request_vars'=>$_REQUEST) ));  wp_die(); } 

В результате выполнения этого кода по ссылке вида wp-admin/admin-ajax.php?action=do_something должен выводиться кусок JSON-а.

Некоторые особенности на бекенде

Наверное, имеет смысл заметить, что хуки в WordPress вешаются каждый раз. Т. е. обработчик нужно регистрировать каждый раз, желательно в файле, который включается каждый раз (в случае с темой это файл functions.php) Если попытаться зарегистрировать AJAX-хук, например, в файлах page.php или index.php темы, хук не будет работать, потому что при обращении к обработчику эти файлы, разумеется, не будут выполняться.

Рекомендуется все функции, повешенные на экшены AJAX-обработчика, заканчивать вызовом wp_die


или функции wp_send_json_success и аналогичных. Или простой die, на худой конец, вызвать.

В случае ошибки обработчик запросов возвращает код 0 или -1 в зависимости от причины ошибки. В частности, в случае, если такого хука не существует (т. е. он не был зарегистрирован по какой-то причине) — возвращается 0.

Функция is_admin, возвращающая true, если пользователь находится в админпанели сайта, будучи вызванной из AJAX-обработчика, всегда возвращает true.

Существует функция check_ajax_referer, которая проверяет реферера (проверяет, откуда произошел запрос) и прерывает выполнение, если реферер какой-то «не такой». Эта функция умеет также проверять
nonce. Подробнее можно почитать в соответствующей статье кодекса.

Передача ссылки на фронтенд

Адрес обработчика запросов — что-то типа wp-admin/admin-ajax.php. Фишка в том, что наш фронтенд "не знает" адреса этой ссылки. Поэтому, если мы хотим, чтобы наша тема или плагин была максимально универсальной и портативной — нам нужно получить в WordPress и передать на фронтенд актуальный адрес этой ссылки:

$ajax_url = admin_url('admin-ajax.php');  

На фронтенд её можно передать самыми разными способами. Зачастую эта ссылка — не единственное, что нужно передавать на фронтенд, поэтому я предпочитаю вставлять её c помощью соответствующего хука в wp_head в теге <script>:

// где-то в functions.php function js_variables(){  $variables = array (  'ajax_url' => admin_url('admin-ajax.php'),  'is_mobile' => wp_is_mobile()  // Тут обычно какие-то другие переменные  );  echo(  '<script type="text/javascript">window.wp_data = ',  json_encode($variables),  ';</script>'  ); } add_action('wp_head','js_variables'); 

Этот хук будет выводить тег <script> с регистрацией глобальных JS-переменных со ссылкой на обработчик в в секции <head> темы (разумеется, для этого нужно вызвать в ней функцию wp_head, что в любом случае рекомендуется делать для любой темы)

Тэг будет вставляться сразу после всех подключенных ассетов (скриптов и таблиц стилей, зарегистрированных через систему ассетов WordPress)

Передать ссылку во фронтенд можно также с помощью функции localize_script. Я нахожу такой подход несколько муторным: де-факто, мы отправляем на фронтенд не наш джаваскрипт из папки assets темы или с какого-нибудь CDN, но его модифицированную версию, при этом не оставляя конечному пользователю выбора (который у него есть, например, в случае с плагинами, склеивающими все скрипты в один и заключается в том, использовать ему эти плагины или нет). Если что — подробнее об подходе с localize_script — в кодексе вордпресса, в статье AJAX In Plugins.

И, разумеется, можно НЕ передавать эту ссылку на фронтенд, а просто её или её часть захардкодить прямо в в JS-файл. Но никто не гарантирует, что в следующей версии WordPress или просто на каком-то другом конкретном энвайрменте URI обработчика будет именно 'wp-admin/admin-ajax.php'. Для универсальности и совместимости рекомендуется всегда использовать функцию admin_url для получения актуальной ссылки на обработчик и передавать её во фронтенд вручную.

Кстати, на всех страницах админки эта ссылка уже проброшена в глобальную переменную ajaxurl в JS. Некоторые плагины вывешивают эту ссылку и для страниц сайта, но на это не стОит рассчитывать (мы ведь не хотим лишних зависимостей для нашего плагина/темы, правда?)

На фронтенде

Теперь мы можем достаточно легко делать веб-запросы к бекенду с нашего фронтенда. Например, если ссылку мы вывесили в переменную wp_data.ajax_url и подключен jQuery — выглядеть это будет примерно вот так:

jQuery(function($){  $.ajax({  type: "GET",  url: window.wp_data.ajax_url,  data: {  action : 'do_something'  },  success: function (response) {  console.log('AJAX response : ',response);  }  }); }); 

Если всё сделано правильно — при запуске выполнится веб-запрос к бекенду, который ответит куском JSON-а, который потом будет получен фронтендом и выведен в консоль.

Любителям ООП

Если вы пытаетесь построить свою собственную архитектуру темы, с автозагрузчиком и ООП, можно определить абстрактный класс вот такого типа:

abstract class AJAX_Handler {   function __construct($action_name) {  $this->init_hooks($action_name);  }   public function init_hooks($action_name) {  add_action('wp_ajax_'.$action_name , array($this,'callback'));  add_action('wp_ajax_nopriv_'.$action_name, array($this,'callback_nopriv'));  }   public function callback_nopriv() {  $this->callback();  }   abstract public function callback();  } 

Теперь достаточно создать для каждого экшена своего наследника этого класса, в котором определить метод callback, после чего создать новый объект класса-наследника, передав в конструктор имя экшена:

class Something extends AJAX_Handler {  function callback() {  wp_send_json_success(array('test'=>'Works!'));  } }  new Something('do_something'); 

На хук wp_ajax_nopriv_XXX вешается метод callback_nopriv, который в родительском классе просто вызывает метод callback, но в наследнике её, разумеется, можно было переопределить. В результате этого при обращении к урл вида /wp-admin/admin-ajax.php?action=do_something получим ответ вида {"success":true,"data":{"test":"Works!"}}.

CORS и возможная беда с протоколом (HTTP/HTTPS)

По соображениям безопасности веб-браузеры ограничивают возможность HTTP-запросов к ресурсам, чей домен отличается от домена, на котором запущен выполняющий эти запросы скрипт. CORS («cross-origin resource sharing») это рекомендованый W3C механизм, позволяющий разрешить кросс-доменные запросы к серверу (со стороны сервера). Если вы хотите сделать из обработчика AJAX-запросов некое подобие API для доступа со сторонних ресурсов (какой бы ужасной ни казалась эта идея, этому может найтись применение) — придется или разрешить кросс-доменные запросы к обработчику, добавив заголовок Access-Control-Allow-Origin, или реализовать API с помощью JSONp.

Если у вас на сайте настроена работа в HTTPS функция admin_url вернёт ссылку с https. Но если на сайте неправильный/истекший SSL-сертификат будет происходить редирект на http-версию сайта и сайт будет просматриваться по протоколу http. В итоге фронтенду достанется ссылка на обработчик в другом протоколе, что, скорее всего, вызовет проблемы. В частности, браузер Firefox, скорее всего, не "обрадуется" этому, решив, что вы пытаетесь делать кросс-доменный запрос.

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

Автор: Илья Андриенко, веб-разработчик DataArt.

habr.com

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

Наиболее распространенное использование AJAX связано с формами – проверка, если берется имя пользователя, или заполнение остальной части формы с различными вопросами в зависимости от конкретного задания, который вы даете. В принципе, вы можете используете AJAX, когда вы хотите событие (как пользователь, нажав что – то, или ввести что – то), привязанную к действию на стороне сервера, которое происходит в фоновом режиме.

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

Обзор: Как использовать AJAX в WordPress

  1. Измените свой собственный шаблон, чтобы включить форму или события JavaScript, которые будут представлять данные с помощью JQuery AJAX для admin-ajax.php включая любые данные, которые вы хотите передать. Убедитесь, что Jquery загружается.
  2. Определим функцию в вашей темы function.php.
  3. Добавим действие крюк AJAX для вашей функции.

Создание формы

Давайте начнем с создания простой формы на переднем конце для ввода новых данных о клиенте. В этом нет ничего сложного, просто вставьте этот код в теле html файла, код выполняет проверку is_user_logged_in ():

if (is_user_logged_in()):?>  <form type="post" action="" id="newCustomerForm">  <label for="name">Имя:</label> <input name="name" type="text" />  <label for="email">Почта:</label> <input name="email" type="text" />  <label for="phone">Телефон:</label> <input name="phone" type="text" />  <label for="address">Адрес:</label> <input name="address" type="text" />  <input type="hidden" name="action" value="addCustomer"/> <input type="submit"> </form> <br/><br/> <div id="feedback"></div> <br/><br/>

Единственное, что может выглядеть странным, что есть использование поля ввода скрытого под названием action – оно содержит имя функции, которое мы будем инициировать через AJAX.

PHP приемник

Затем откройте functions.php и добавьте следующую строку, чтобы убедиться, что Jquery загружается на вашем сайте:

wp_enqueue_script ( 'JQuery');

 

Базовая структура для написания вызова AJAX выглядит следующим образом:

function myFunction(){ //do something die(); } add_action('wp_ajax_myFunction', 'myFunction'); add_action('wp_ajax_nopriv_myFunction', 'myFunction');

 

Эти две последних строки крючки действия, которые говорят WordPress «У меня есть функция под названием myFunction, и я хочу, чтобы вы послушали ее, потому что она будет вызываться через интерфейс AJAX» – первый для пользователей уровня администратора, в то время как wp_ajax_nopriv_ является для пользователей, которые не вошли в систему. Вот полный код в functions.php, который мы будем использовать, чтобы вставить данные в специальной таблицы клиентов, которые мы объясним коротко:

wp_enqueue_script('jquery');  function addCustomer(){  global $wpdb;  $name = $_POST['name']; $phone = $_POST['phone']; $email = $_POST['email']; $address = $_POST['address'];  if($wpdb->insert('customers',array( 'name'=>$name, 'email'=>$email, 'address'=>$address, 'phone'=>$phone ))===FALSE){  echo "Ошибка";  } else { echo "Customer '".$name. "' успешно добавлено, строка ID = ".$wpdb->insert_id;  } die(); } add_action('wp_ajax_addCustomer', 'addCustomer'); add_action('wp_ajax_nopriv_addCustomer', 'addCustomer'); // на самом деле не нужна

 

Так же, как и прежде, мы объявили global $wpdb, чтобы дать нам прямой доступ к базе данных. Мы затем захватываем переменную POST, которая содержат данные формы. Окруженный в операторе IF функцию $ wpdb-> insert, мы используем для вставки данных в нашу таблицу. Поскольку WordPress предоставляет специальные функции для вставки регулярных постов и мета – данных, метод $ wpdb-> insert обычно используется только для пользовательских таблиц. Вы можете прочитать об этом на Кодексе, но в основном это принимает имя таблицы, которая будет вставлена, а затем с помощью array из column/value pairs.

=== FALSE проверяет, не удалась ли функция вставки, и если да, то он выдает “ошибка“. Если нет, то мы просто посылаем сообщение пользователю, что был добавлен Клиент X, и показываем переменную $wpdb-> insert_id, которая указывает на переменную auto-increment последней операции вставки, что произошло (предполагается, что вы установили поля, которые автоматически приращиваються, как идентификатор) .

И, наконец, die() переопределяет по умолчанию die(0), предоставленную WordPress – это не важно, как таковой, но без нее вы собираетесь получить 0 к концу, что бы отправить обратно в шаблон.

Javascript

Последним шагом является фактический Javascript, который будет инициировать вызов AJAX. Вы заметите, что в форме, которую мы добавили ранее, поле действия было оставлено пустым. Это потому, что мы будем отвергать с нашим вызовом AJAX. Общий способ сделать это такой:

jQuery.ajax({  type:"POST",  url: "/wp-admin/admin-ajax.php", // наш обработчик файла PHP  data: "myDataString",  success:function(results){  // что-то делать с возвращаемыми данными  }  )};

 

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

<script type="text/javascript"> jQuery('#newCustomerForm').submit(ajaxSubmit);  function ajaxSubmit(){  var newCustomerForm = jQuery(this).serialize();  jQuery.ajax({ type:"POST", url: "/wp-admin/admin-ajax.php", data: newCustomerForm, success:function(data){ jQuery("#feedback").html(data); } });  return false; } </script>

 

В первой строке мы прикрепили функцию ajaxSubmit формы, которую мы сделали раньше – так что, когда пользователь нажимает кнопку отправить, он проходит через нашу специальную функцию AJAX. Без этого наша форма ничего не будет делать. В нашей функции ajaxSubmit(), первое, что мы сделаем, чтобы serialize() форму. Это просто принимает все значения формы, и превращает их в одну длинную строку, которую наш PHP будет разобрать позже. Если все работает правильно, мы поместим возвращаемые данные в div с идентификатором обратной связи.

Вот и все. Сохраните все, обновите и попробуйте отправить некоторые данные формы.

Что нужно иметь в виду

Безопасность : Этот код не является производством готового и предназначен только для целей обучения. Мы оставили одну ключевую точку, это использование WP-nonce – разовый код, сгенерированный WordPress, который обеспечивает запрос AJAX, откуда он был призван; Ключ доступа. Без этого ваша функция эффективно может быть использована для вставки случайных данных. Атаки инъекции SQL не проблема, хотя, потому что мы перенаправили запросы через WordPress функцию $wpdb->insert – WordPress, которая очищает любые входы для вас и делает их безопасными.

Обновление таблицы клиентов: На данный момент мы только отправили обратно сообщение с подтверждением, но таблица клиентов не обновляется – вы будете видеть только дополнительные записи, если вы обновите страницу (такой вид теряет смысл, если делать это все через AJAX). Смотрите, если вы можете сделать новую функцию AJAX, которая может динамически выводить таблицу.

Проверка ввода: потому не происходит никакой проверки с формой данных, на самом деле можно добавить пустые записи или несколько записей, если нажать слишком много раз. Некоторые входные проверки на полях формы, очищая их, когда завершено, а также SQL для проверки электронной почты или номер телефона, который не существует в базе данных было бы полезно.

andreyex.ru

AJAX запросы и admin-ajax.php

AJAX — это асинхронные HTTP запросы выполняемые на странице с помощью языка JavaScript, позволяющие общаться с веб-сервером без полной перезагрузки страницы. Это позволяет делать интерфейсы более быстрыми, отзывчивыми и динамичными.

В WordPress такой подход используется во многих местах: работа с медиафайлами, автоматическое сохранение записей, управление ревизиями, работа с произвольными полями, работа с виджетами и многое другое. И чтобы каждый раз не изобретать велосипед, файл admin-ajax.php в WordPress предоставляет удобный API для работы с AJAX запросами.

В данной статье мы не будем рассматривать сам API, но стоит отметить, что несмотря на присутствие слова «admin» в названии файла, через него могут проходить запросы и с лицевой части сайта, включая анонимные запросы из тем и плагинов WordPress. К сожалению многие источники ошибочно советуют отключить этот файл, или заблокировать его паролем — этого делать не стоит.

Большое количество запросов на admin-ajax.php

Как мы уже упомянули, файл admin-ajax.php вызывается при автоматическом сохранении записей, а также для обновления блокировок, чтобы два пользователя не могли редактировать одну и ту же запись одновременно. Это реализует API в WordPress под названием Heartbeat (сердцебиение), который построен на базе admin-ajax.php.

При редактировании записи Heartbeat отправляет запрос на admin-ajax.php каждые 15 секунд (или каждые 60 секунд, в случае если вкладка в браузере не является активной). Поэтому если вы видите в логах вашего веб-сервера большое количество запросов на admin-ajax.php стоит их проанализировать.

  • С каких IP адресов приходят эти запросы
  • С какой периодичностью они приходят
  • Сколько времени в среднем занимает один такой запрос
  • Каково содержание запроса

Итак, если эти запросы приходят с вашего IP адреса, или с IP адресов редакторов на вашем сайте, если их периодичность около 15-60 секунд, если каждый такой запрос занимает не более 0.5 сек, и содержание запросов не содержит ничего необычного, то все в порядке — файл admin-ajax.php не является источником нагрузки на ваш сервер, независимо от «большого» количества запросов. А если ваш хостинг-провайдер уверяет вас в обратном, то советуем задуматься о его компетентности и о возможном переезде.

Когда admin-ajax.php действительно является проблемой

Рассмотрим несколько вариантов, когда admin-ajax.php действительно становится источником высокой нагрузки на ваш сервер, и как бороться с этой нагрузкой.

Запросы на admin-ajax.php занимают более 1 секунды

В среднем запросы на admin-ajax.php могут занимать около 300 мс. Если же на вашем сайте данные запросы выполняются более чем за одну секунду, то необходимо разобраться. Используйте средства профилирования, чтобы понять чем именно занят процесс все это время. Наверняка вы найдете медленную функцию в вашей теме или плагине, которая не имеет никакого отношения к AJAX запросам.

Если же вы не владеете средствами профилирования, или у вас нет времени разбираться в чужом коде, то попробуйте отключить все плагины и активировать стандартную тему WordPress. Затем активируйте плагины по порядку, чтобы понять какой из них является причиной медленных запросов на admin-ajax.php.

Бывает и такое, что запросы на admin-ajax.php становятся медленными не из-за конкретных плагинов или тем, а из-за неоптимальной конфигурации сервера MySQL. Такое бывает достаточно редко, и в этом случае следует заняться оптимизацией сервера базы данных.

Подозрительное содержание запроса

Файл admin-ajax.php (и admin-post.php) часто выбирается злоумышленниками для того, чтобы использовать известную уязвимость в каком-нибудь плагине. В качестве примера можно привести недавний инцидент с популярным плагином FancyBox, где именно admin-ajax.php (или admin-post.php) послужил точкой входа.

Эти файлы выбираются не спроста, ведь каждый из них исполняет событие admin_init даже для анонимных HTTP запросов. Многие разработчики плагинов и тем, ошибочно считают, что раз выполняется событие admin_init, значит пользователь выполнил вход и имеет права администратора. Это не так. Повторяем — событие admin_init выполняется даже для анонимных HTTP запросов.

Итак, в случае с уязвимостью плагина FancyBox for WordPress, вот примерно то, как выглядит «подозрительное содержание запроса»:

46.4.76.174 – – [04/Feb/2015:00:25:09 -0500] "POST /wp-admin/admin-ajax.php?page=fancybox-for-wordpress HTTP/1.1" 403 4207 INPUTBODY:action=update&mfbfw%5Bext...  

Если вы обнаружили подобный запрос, необходимо понять на какой конкретно плагин или тему он нацелен, что именно он пытается сделать, удалось ли ему это. В подобных случаях мы рекомендуем обратиться к экспертам по безопасности WordPress.

Неузнаваемые IP адреса

Этот пункт тесно связан с предыдущим. Если вы увидели запросы на admin-ajax.php с неузнаваемых IP адресов, то необходимо проанализировать эти запросы, и понять чего именно пытается сделать злоумышленник. IP адреса можно заблокировать, например по шаблону с помощью fail2ban.

Слишком частая периодичность запросов

Как мы уже упомянули, на активной вкладке при редактировании записи, WordPress выполняет AJAX запрос каждые 15 секунд, т.е. для достижения 1 запроса в секунду на сервере, вам необходимо 15 редакторов с открытой вкладкой. Если вы являетесь единственным редакторов на вашем сайте, а запросов на admin-ajax.php с вашего IP адреса более 1 в секунду (мы встречали и 20/с), то стоит с этим разобраться.

Самой частой причиной подобного поведения является тема или плагин, поэтому следует их деактивировать и включать по порядку, чтобы найти источник. Здесь стоит также упомянуть плагин Heartbeat Control, который позволяет изменять стандартную конфигурацию Heartbeat в WordPress, но учтите, что отключив Heartbeat вы скорее временно скрываете проблему, а не устраняете ее.

Заключение

В этой статье мы рассмотрели несколько причин, по которым может возникать высокая нагрузка на хостинг-площадку через файл admin-ajax.php, но не исключено, что могут быть и другие.

В случае с любой «лишней» нагрузкой на сервер, рекомендуем всегда проверять факты, средства профилирования — ваши лучшие друзья. Результаты порой бывают удивительными, когда например некоторые из очень популярных плагинов для WordPress оказываются самыми медленными.

wpmag.ru

Параметры действия

В предыдущем примере, параметр действия spyr_plugin_do_ajax_request отвечает за связь между файлом JavaScript и кодом PHP. Рекомендуется все действия, включая и это, использовать с префиксами; таким образом, оно становится уникально и легко может быть идентифицировано. Сделать так, чтобы было видно, что оно принадлежит плагину WordPress.

Отдельные действия Ajax для WordPress

Существует два отдельных действия Ajax для WordPress, которые мы можем использовать.
Во-первых, wp_ajax_$action, которое обрабатывает запрос Ajax, если пользователь вошел в систему.
Во-вторых, wp_ajax_nopriv_$action, которое обрабатывает запрос Ajax, если пользователь не вошел в систему, и не имеет никаких привилегий.

Исходя из наших предыдущих примеров, нам нужно добавить эти обращения действий в наш плагин следующим образом:

Теперь, когда мы знакомы с основными принципами того, как события Ajax взаимодействуют с WordPress, давайте рассмотрим реальный пример. Давайте создадим простой плагин, который позволит администраторам удалять определенные записи на стороне клиента.

Плагин Ajax для удаления записей

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

  • Добавления файла JavaScript со скриптом Ajax;
  • Добавления в каждую запись ссылки, которая при нажатии будет удалять запись;
  • Обработки Ajax-запроса к PHP;
  • Обработки клика кнопки с помощью JQuery;
  • Добавления скрипта в очередь обработки.

Обеспечение безопасности всегда стоит на первом месте. Поэтому мы должны проверить, имеет ли текущий пользователь достаточные права, чтобы видеть ссылку «Удалить«. Мы также должны убедиться, что мы имеем дело с одиночной записью, в противном случае нет никакого смысла добавлять ссылку «Удалить«.

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

Мы должны соответствовать политике Ajax, согласно которой запросы и ответы должны иметь то же происхождение. Все запросы и ответы Ajax должны обрабатываться с того же домена; и протоколы также должны соответствовать.

В WordPress можно установить протокол https в панели администрирования вашего сайта, задав для параметра «FORCESSLADMIN» значение ‘true’ в конфигурационном файле WordPress. Отправка запроса с адреса http://example.com/sample-post/ на адрес https://example.com/wp-admin/admin-ajax.php не будет работать. Даже если мы установили https:// на стороне сервера, мы можем выполнить вызов admin-ajax.php без https://.

Наконец, последняя значимая строка кода выводит динамические переменные, которые будут использоваться в ajax-delete-posts.js:

Добавление ссылки «Удалить» к содержимому страницы

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

Он использует следующую структуру, префикс_плагин-действие-идентификатор, где префикс — это spyr, adp = Ajax Delete Post, действие — это наше действие удаления, а идентификатор — ID удаляемого поста. Это не обязательно, но такой формат рекомендуется при составлении плагинов.

Обратите внимание, что мы также добавляем к ссылке ID записи и nonce, используя при этом атрибуты данных HTML5. Последний шаг — это прикрепить сформированную ссылку к содержимому страницы.

Обработка запросов Ajax с помощью PHP и WordPress

Мы уже дошли до половины статьи. Далее мы рассмотрим код, который на самом деле управляет представлением вашего Ajax запроса. Изучите его внимательно, поскольку он опирается на то, как вы называете данные, представленные запросом JQuery для получения идентификатора записи (pid) и значения nonce:

spyr_adp_ajax_delete_post — это имя действия передается в ответ на запрос файла JavaScript. Это подразумевает, что полное имя для вашего действия будет wp_ajax_spyr_adp_ajax_delete_post. Значения ID и nonce записи также передаются с помощью файла JavaScript, и мы можем получить их от $_REQUEST.

Мы собираемся установить экземпляр объекта WP_Ajax_Response, который позволит нам вернуть необходимый XML-ответ. После этого вы можете считать этот результат и действовать в соответствии с ним через JQuery.

Опять же, перед удалением записи вы должны убедиться, что пользователь является администратором, и значения nonce совпадают. Вы должны создать различные ответы для каждого сценария, так чтобы вы точно знали, была ли запись удалена или нет.

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

На сервер для обработки запрос отправляется очень просто:

action=spyr_adp_ajax_delete_post&pid=403&nonce=878727e18a

В качестве примера сформированного XML-файла, полученного в ответе, можно рассмотреть следующее:

Обработка нажатия на кнопку с помощью JQuery

Единственное, что нам осталось рассмотреть, это создание кода JavaScript, который будет отправлять запрос и обработать ответ. Сам код довольно понятен, но я все же добавил в него комментарии, чтобы он стал еще проще для понимания:

Разбирается XML через JQuery очень просто, мы просматриваем XML на наличие элементов с помощью jQuery.find();, как если бы мы пытались найти элемент в HTML-документе.

Заключение

Как видите, выполнение запросов Ajax в ваших плагинах и темах WordPress является довольно простым процессом. В частности, это делается еще проще, благодаря двум специальным действиям: wp_ wp_ajax_$action и wp_ajax_nopriv_$action.

Это только начало удивительного пути, на котором вы сможете писать код, позволяющий обойтись без повторных загрузок страницы и делающий ваши темы и плагины WordPress более интерактивными. Что вы дальше хотите с этим сделать?

Если вы хотите получить дополнительную информацию по этой теме, ознакомьтесь с разделом Кодекса WordPress по Ajax и Ajax в плагинах.

Перевод статьи «Adding Ajax to Your WordPress Plugin» был подготовлен дружной командой проекта Сайтостроение от А до Я.

www.internet-technologies.ru

Использование ajax при отправке формы позволяет отправить форму без перезагрузки страницы. В WordPress это достаточно просто реализовать. Допустим, у нас есть следующая форма заказа звонка:

<form class="form-container recall-form-validate">  <div class="form-title"><h2>Заказать звонок</h2></div>  <div class="form-title">Введите Ваше имя:</div>  <input class="form-field form-name" type="text" name="name" /><br />  <div class="form-title">Введите номер телефона:</div>  <input class="form-field form-tel" type="text" name="tel" /><br />  <div id="submit-ajax" class="submit-container">  <input class="submit-button" type="submit" value="Отправить"/>  </div> </form>

Теперь напишем скрипт, обрабатывающий событие нажатия на кнопку «Отправить»:

$(".submit-button").on("click", function (event) {  event.preventDefault();  var name = $(".form-name").val();  var tel = $(".form-tel").val();  $.ajax({  url: "/wp-admin/admin-ajax.php",  method: 'post',  data: {  action: 'ajax_order',  name: name,  tel: tel   },  success: function (response) {  $('#submit-ajax').html(response);  }  });  }); 

Скрипт отменяет отправку данных на сервер, затем записывает значения полей формы и отправляет их через ajax. Получив результат обработки запроса, скрипт выводит в блоке с id = submit-ajax сообщение, полученное от сервера.

Осталось написать функцию, которая будет обрабатывать отправленные на сервер данные (её можно поместить в файл темы functions.php):

function ajax_form(){  $name = $_REQUEST['name'];  $tel = $_REQUEST['tel'];  $response = '';  $thm = 'Заказ звонка';  $thm = "=?utf-8?b?". base64_encode($thm) ."?=";  $msg = "Имя: ".$name."<br/>  Телефон: ".$tel ."<br/>";  $mail_to = 'здесь адрес почты, на которую будет отправляться сообщение';  $headers = "Content-Type: text/html; charset=utf-8n";  $headers .= 'From: имя отправителя' . "rn";  // Отправляем почтовое сообщение   if(mail($mail_to, $thm, $msg, $headers)){  $response = 'Сообщение отправлено';  }else  $response = 'Ошибка при отправке';  // Сообщение о результате отправки почты   if ( defined( 'DOING_AJAX' ) && DOING_AJAX ){  echo $response;  wp_die();  } }  add_action('wp_ajax_nopriv_ajax_order', 'ajax_form' ); add_action('wp_ajax_ajax_order', 'ajax_form' );

 



inprocess.by

@Daniel

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

Правила большого пальца:

  • В соответствии со стандартами WordPress все запросы ajax должны поступать на «ajaxurl» в javascript. Он фактически содержит путь файла wp-admin/admin-ajax.php.

    Пример:

    $.ajax({  url: ajaxurl,  data: {'action':'generateCptApiKey'},  success:function(data) {  console.log(data);  },  error: function(errorThrown){  console.log(errorThrown);  } }); 

Если вы делаете какой-нибудь sutff в разделе wp-admin dashboard или связаны с разделом wp-admin, например , создающим страницу параметров в области панели управления wp-admin, чем «ajaxurl» будет всегда доступна в javascript.

Если этот запрос ajax инициализируется с front end page/post, вам нужно указать путь admin-ajax.php, используя следующий метод и лучше, если вы локализовать это для front-end javascript, поэтому он будет доступен в переменной javascript, как это доступно в разделе панели управления wp-admin.

Для этого нам нужно добавить еще несколько строк кода.

Метод:

Обновленный внешний код ajax для кода примера:

// Register the script wp_register_script( 'ajaxsettings', 'path/to/ajaxsettings.js' );  // Localize the script with new data $ajaxsettings = array(  'ajaxurl' => admin_url('admin-ajax.php') ); wp_localize_script( 'ajaxsettings', 'ajaxsettings', $ajaxsettings );  // Enqueued script with localized data. wp_enqueue_script( 'ajaxsettings' );  $.ajax({  url: ajaxsettings.ajaxurl,  data: {'action':'generateCptApiKey'},  success:function(data) {  console.log(data);  },  error: function(errorThrown){  console.log(errorThrown);  }  }); 

После этого нам нужно написать метод для обработки этого запроса ajax и отправить результат обратно на вызов ajax.

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

Таким образом, в основном для обработки запроса ajax ниже приведены два крючка:

  • wp_ajax_ (действие): он обрабатывает запрос от пользователей, прошедших проверку подлинности/регистрации. (Используется для задач, связанных с домашней страницей wp-admin).
  • wp_ajax_nopriv_ (действие): Он обрабатывает внешние аутентифицированные запросы. (Используется для задач, связанных с главной страницей/отправкой ajax-вызовов)

Здесь (действие) — это имя метода, которое вы должны закодировать в текущем файле темы function.php, и этот метод будет обрабатывать этот запрос ajax.

<сильные > Примеры:

Объектно-ориентированный стиль:

add_action( 'wp_ajax_cleanResponseFiles', array($this, 'cleanResponseFiles')); add_action( 'wp_ajax_nopriv_cleanResponseFiles', array($this, 'cleanResponseFiles')); 

Примечание. Здесь «cleanResponseFiles» — это метод класса, который будет обрабатывать запрос ajax. и $это указывает текущий объект класса.

Процедурный стиль:

add_action( 'wp_ajax_cleanResponseFiles', 'cleanResponseFiles'); add_action( 'wp_ajax_nopriv_cleanResponseFiles','cleanResponseFiles'); 

Примечание. Здесь «cleanResponseFiles» добавляется функция в текущий файл theme.php темы, и он будет обрабатывать запрос ajax.

В этом мы рассматриваем, что запрос ajax может быть сделан либо из панели управления wp-admin, либо из front-end page/post.

Пример метода обработчика запроса ajax:

function cleanResponseFiles(){  echo "<pre>";  print_r($_POST);  echo "</pre>";   //Always use exit() in ajax request handler function end  exit(); } 

Правило большого пальца:

  • Всегда используйте метод exit() в методе обработчика запроса ajax, это важно.
  • Лучшей практикой отправки запроса ajax является использование WordPress_nonce.

Это просто для avoding CRSF (подделка запроса на межсайтовый запрос), добавив Honeypot, скрытое поле ввода с генерируемым случайным ключом и в методе обработчика запроса оно должно быть проверено.

Это методы, которые мы можем использовать для создания Wordcepress nonce и проверки обработчика запроса WordPress nonce и ajax или простого обработчика HTTP-запросов.

Методы WordPress Nonce:

  • wp_create_nonce: используется для создания случайного ключа для отправки в виде скрытого поля.
  • wp_verify_nonce: используется для проверки случайного ключа в методе обработчика запросов.

В этом комментарии я приложу рабочий пример wordpress ajax call ASAP.

qaru.site


You May Also Like

About the Author: admind

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

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

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.