У jQuery заготовлено несколько методов для ассинхронного обмена данными с сервером. Один из них ($.load()) мы уже рассмотрели в предыдущей статье. Давайте рассмотрим остальные методы, которые мы будем использовать для обработки данных.

jQuery.get() или $.get()

Осуществляет запрос к серверу методом GET без перезагрузки страницы. Это сокращенный вариант функции $.ajax().

$.get(url,[data],[callback],[dataType])

У этого метода один обязательный параметр - url. Но нам нужны будут все - data нам пригодится, чтобы передавать на сервер наши данные, callback - в этой функции мы будет обрабатывать ответ с сервера, dataType - чтобы можно было работать с JSON данными. Поясню, почему нам нужен последний параметр. Если его не указывать, то возвращаемые данные с сервера придут в виде строки. Для самого простого варианта это сгодится. Но если нам нужно вернуть с сервера разные данные, да ещё выполнить определенные действия в зависимости от ответа, то тут как раз и пригодятся возможности JSON.

Для данного типа данных у jQuery есть уже готовый метод $.getJSON(). Этот метод аналогичен $.get(), только без четвертого параметра. У него в качестве типа данных уже указан JSON.

Вызов этого метода будет выглядеть приблизительно так

$.getJSON('/assets/ajax.php', {action:'getContent', id:5}, function(response) {
    if (response.success) {
        // Запрос выполнен успешно
    	// Вставляем содержание страницы
    	$('#content').html(response.data);
	} else {
	    // Запрос вернулся с сообщением об ошибке
	    alert(response.message)
	}
})

А вот так выглядит контроллер ajax.php, на который мы будем посылать наш ajax запрос. А он должен вернуть ответ в JSON формате.

<?php
// Если запрос не AJAX или не передано действие, выходим
if ($_SERVER['HTTP_X_REQUESTED_WITH'] != 'XMLHttpRequest' || empty($_REQUEST['action'])) {exit();}

$action = $_REQUEST['action'];

define('MODX_API_MODE', true);
require_once dirname(dirname(__FILE__)).'/index.php';

$modx->getService('error','error.modError');
$modx->getRequest();
$modx->setLogLevel(modX::LOG_LEVEL_ERROR);
$modx->setLogTarget('FILE');
$modx->error->message = null;

switch ($action) {
    case 'getContent':
        // Если не передан id страницы, то указывает сообщение об ошибке
        $id = isset($_REQUEST['id']) ? (int) $_REQUEST['id'] : 0;
        if (empty($id)) {
            $response = array('success'=>false,'message'=>'Не указан идентификатор страницы!');
        } else {
            $object = $modx->getObject('modResource',$id);
            $output = $object->get('content');
            // Парсим теги MODX
            $maxIterations= (integer) $modx->getOption('parser_max_iterations', null, 10);
            $modx->getParser()->processElementTags('', $output, false, false, '[[', ']]', array(), $maxIterations);
            $modx->getParser()->processElementTags('', $output, true, true, '[[', ']]', array(), $maxIterations);
            $response = array('success'=>true,'data'=>$output);
        }
}

@session_write_close();
// Возвращаем ответ в JSON формате
exit($modx->toJSON($response));

Обратите внимание, что в случае ошибки, ajax-контроллер возвращает такой ответ

{"success":false,"message":"Не указан идентификатор страницы"}
А в случае успеха такой
{"success":true,"data":"Содержание указанной страницы"}

Как видите, ответы разные. В зависимости от ключа "success" мы выполняем соответствующие действия - или вставляем содержание страницы в нужный узел HTML или выводим сообщение об ошибке. Если нужно вернуть больше значений, то добавляйте в массив $response нужные ключи, а в javascript файле ловите их. Так работает адмика MODX, например. Если посмотреть на загрузку дерева ресурсов, то можно увидеть несколько post-запросов типа такого

{"success":true,"total":"10","results":[{id:1,"templatename":"MainTemplate",...}]

jQuery.post() или $.post()

Этот метод аналогичен $.get(), но использует метод POST для связи с сервером. Как правило, $.post() используют при работе с формами. Вызывается он аналогично $.get()

// Вешаем на событие сохранения формы
$(":submit").on("submit", function(e){
    //Отменяем стандартное действие. Вместо него мы сами сделаем то, что нам надо.
    e.preventDefault();
    // Передаем в параметре formdata данные формы. Если их немного, то можно указать их вручную.
    $.post('/assets/ajax.php', {action:'getContent', formdata:$('form').serializeArray()}, function(response) {
        if (response.success) {
            // Запрос выполнен успешно
        	// Вставляем содержание страницы
        	$('#content').html(response.data);
    	} else {
    	    // Запрос вернулся с сообщением об ошибке
    	    alert(response.message)
    	}
    }, 'json');
});

Запрос ушёл на сервер с помощью POST метода с двумя параметрами action и formdata. В файле ajax.php ловим эти параметры в массиве $_POST и работаем с ними. Единственный момент - данные в параметре formdata в не очень удобном виде

[{name:"поле1", value:"значение поля1"}, {name:"поле2", value:"значение поля2"}]
Их нужно перевести в привычний формат. Для этого выполним простейшее преобразование

$data = array();
if (!empty($_POST['formdata'])) {
    foreach ($_POST['formdata'] as $field_data) {
        $data[$field_data['name']] = $field_data['value'];
    }
}

Теперь данные лежат в массиве $data в привычном формате "имя поля"=>"значение" и можно работать с ним также как с массивом $_POST. Только на забывайте обрабатывать данные перед использованием.

06 января 2016, 14:23   1764     13

Комментарии ()

  1. kepamuk 02 февраля 2017, 21:47 # 0
    такой вопрос, а как все это работает без
    header('Content-type: text/json');
    в php файле?
    1. kepamuk 02 февраля 2017, 21:49 # 0
      хотя если честно у меня никак не работает
      1. Сергей Шлоков 02 февраля 2017, 22:12 # 0
        Что не работает? Отправка? Получение? jQuery подключен?
        1. kepamuk 02 февраля 2017, 22:17 # 0
          Работает вот такая штука joxi.ru/YmEnVqXs0B7kp2, если делаю вот так молчит намертво joxi.ru/bmoWoBMfx7nL6m может нужно что то подключить?
          1. Сергей Шлоков 02 февраля 2017, 22:22 # 0
            А чем разница?
            1. kepamuk 02 февраля 2017, 22:23 # 0
              в том что первый вариант работает
              exit(json_encode($a);
              а второй нет
              exit($modx->toJSON($a));
              
            2. Сергей Шлоков 02 февраля 2017, 22:24 # 0
              А ну понятно. Переменной $modx не существует.
              1. kepamuk 02 февраля 2017, 22:24 # 0
                да, как её подключить?
                1. Сергей Шлоков 02 февраля 2017, 22:27 # 0
                  Раскомментировать строчки выше. Как минимум до 17-й.
                2. kepamuk 02 февраля 2017, 22:26 # 0
                  я думал что вот это поможет
                  define('MODX_API_MODE', true);
                  require_once dirname(dirname(__FILE__)).'/index.php';
                  но все равно не помогает
                  1. Сергей Шлоков 02 февраля 2017, 22:27 # +1
                    Судя по коду, файл ajax.php находится в корне. Значит один dirname нужно убрать.
                    1. kepamuk 02 февраля 2017, 22:30 # 0
                      все работает извините за тупость я еще нубчег
          2. kepamuk 03 февраля 2017, 23:09 # 0
            Жаль что не описываете для чего нужно например это
            $modx->getService('error','error.modError');
            $modx->getRequest();
            $modx->setLogLevel(modX::LOG_LEVEL_ERROR);
            $modx->setLogTarget('FILE');
            $modx->error->message = null;
            это
            $modx->getParser()->processElementTags
            или это
            @session_write_close();
            конечно гугл в помощь, но конкретно для вашего примера мне как новичку не понятно для чего все это

            Вы должны авторизоваться, чтобы оставлять комментарии.

            Выделите опечатку и нажмите Ctrl + Enter, чтобы отправить сообщение об ошибке.