Javascript — асинхронные ajax запросы на примерах

Содержание раздела:

Пример использования

<!DOCTYPE html>
<html>
	<head>
		<title>Использование функции $.ajax()</title>
		<script src = "https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
		<script>
	$( document ).ready(function(){
	  $( "button" ).click(function(){ // задаем функцию при нажатиии на элемент <button>
	    $.ajax({
	      method: "POST", // метод HTTP, используемый для запроса
	      url: "about.php", // строка, содержащая URL адрес, на который отправляется запрос
	      data: { // данные, которые будут отправлены на сервер
	        name: "Denis",
	        city: "Erebor"
	      },
	      success: function ( msg ) { // функции обратного вызова, которые вызываются если AJAX запрос выполнится успешно (если несколько функций, то необходимо помещать их в массив)
	        $( "p" ).text( "User saved: " + msg ); // добавляем текстовую информацию и данные возвращенные с сервера
	      },
	      function () { // вызов второй функции из массива
	        console.log( "next function" );
	      }],
	      statusCode: {
	        200: function () { // выполнить функцию если код ответа HTTP 200
	          console.log( "Ok" );
	        }
	      }
	    })
	  });
	});
		</script>
	</head>
	<body>
		<button>Клик</button>
		<p></p>
	</body>
</html>

В этом примере с использованием jQuery функции $.ajax() мы при нажатии на элемент <button> (кнопка) выполняем асинхронный AJAX запрос со следующими параметрами:

method — указываем метод HTTP POST, используемый для запроса.

url — файл, к которому мы обращаемся («about.php»), он содержит следующий PHP код:

<?php $name = $_POST; // создаем переменную name, которая содержит переданные скрипту через HTTP метод POST данные (с ключом name)
$city = $_POST; // создаем переменную name, которая содержит переданные скрипту через HTTP метод POST данные (с ключом city)
echo $name.», «.$city; // выводим текстовое содержимое (значение выше созданных переменных, перечисленных через запятую)
?>

data — данные, которые будут отправлены на сервер.

success — функции обратного вызова, которые вызываются если AJAX запрос выполнится успешно

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

statusCode — объект числовых кодов HTTP и функции, которые будут вызываться, когда код ответа сервера имеет соотвествующее значение (определенный код HTTP)

В нашем случае код 200.

Результат нашего примера:


Пример использования jQuery функции .ajax()

В следующем примере мы выполним AJAX запрос с помощью которого загрузим и выполним файл JavaScript.

<!DOCTYPE html>
<html>
	<head>
		<title>Использование функции $.ajax()</title>
		<script src = "https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
		<script>
	$( document ).ready(function(){
	  $( "button" ).click(function(){ // задаем функцию при нажатиии на элемент <button>
	    $.ajax({
	      method: "GET", // метод HTTP, используемый для запроса
	      url: "ajax_script.js", // строка, содержащая URL адрес, на который отправляется запрос
	      dataType: "script" // расценивает ответ как JavaScript и возвращает его как обычный текст
	    })
	  });
	});
		</script>
	</head>
	<body>
		<button>Клик</button>
		<p></p>
	</body>
</html>

В этом примере с использованием jQuery функции $.ajax() мы при нажатии на элемент <button> (кнопка) выполняем асинхронный AJAX запрос, который загружает скрипт JavaScript и выполняет его. Запрос имеет следующие параметры:

  • method — указываем метод HTTP GET, используемый для запроса.
  • url — файл, к которому мы обращаемся («ajax_script.js»), он содержит следующий JavaScript код:

    $( "p" ).text( "Hello" ); // находим элемент <p> и добавляем текстовое содержимое
    
  • dataType — определяет тип данных, который вы ожидаете получить от сервера (скрипт будет выполнен даже если не указать этот параметр).

Результат нашего примера:


Пример использования jQuery функции .ajax()jQuery AJAX

Примеры

Пример: Выполняется запрос на страницу test.php, но не выполняется обработка данных.

jQuery.post("test.php");

Пример: Запрос на страницу test.php с отправкой некоторых данных (без обработки полученных данных).

jQuery.post("test.php", { name: "John", time: "2pm" } );

Пример: Передается массив данных на сервер (без обработки полученных данных).

jQuery.post("test.php", { 'choices[]': } );

Пример: отправка данных формы используя Ajax-запрос.

jQuery.post("test.php", jQuery("#testform").serialize());

Пример: Оповещаем об успешном получении данных со страницы test.php (HTML или XML, в зависимости от полученных данных).

jQuery.post("test.php", function(data) {
    alert("Data Loaded: " + data);
});

Пример:Оповещаем об успешном получении данных со страницы test.cgi с дополнительной отправкой данных (HTML или XML, в зависимости от полученных данных).

jQuery.post("test.php", { name: "John", time: "2pm" })
.done(function(data) {
    alert("Data Loaded: " + data);
});

Пример: Получить содержимое страницы test.php, возвращаемые в JSON-формате (<?php echo json_encode(array(«name»=>»John»,»time»=>»2pm»)); ?>), и вывести их на страницу.

jQuery.post("test.php",
    function(data) {
        $('body').append( "Name: " + data.name ) // John
            .append( "Time: " + data.time ); // 2pm
    }, "json"
);

Пример: Отправка данных формы используя Ajax-запрос и вставка полученных данных в div.

<!DOCTYPE html>
<html>
<head>
    <script src="http://code.jquery.com/jquery-1.9.1.js"></script>
</head>
<body>
    <form action="/" id="searchForm">
        <input type="text" name="s" placeholder="Search..." />
        <input type="submit" value="Search" />
    </form>
    <!-- результат будет вставлен внутрь следующего div -->
    <div id="result"></div>
    <script>
        //    добавляем обработчик сабмита формы
        $("#searchForm").submit(function(event) {
            //    запрещаем стандартный функционал обработчика формы
            event.preventDefault();
            //    получаем некоторые данные из элементов страницы
            var $form = $( this ),
            term = $form.find( 'input' ).val(),
            url = $form.attr( 'action' );
            //    отпправляем данные на сервер POST-запросом
            var posting = $.post( url, { s: term } );
            //    вставляем полученные результаты
            posting.done(function( data ) {
                var content = $( data ).find( '#content' );
                $( "#result" ).empty().append( content );
            });
        });
    </script>
</body>
</html>

Защита: используем nonce и проверяем права

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

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

Существует два вида защиты, которые нужно использовать в AJAX запросах в большинстве случаев.

1. Код nonce (случайный код)

Nonce — это уникальная строка, которая создается и используется один раз — одноразовое число. Nonce проверка используется, когда нужно убедится, что запрос был послан с указанного «места».

В WordPress есть функции wp_create_nonce() и check_ajax_referer() — это базовые функции для создания и последующей проверки nonce кода. С их помощью мы и будем создавать защиту nonce для AJAX запросов.

Для начала создадим nonce код:

add_action( 'wp_enqueue_scripts', 'myajax_data', 99 );
function myajax_data(){

	wp_localize_script('twentyfifteen-script', 'myajax', 
		array(
			'url' => admin_url('admin-ajax.php'),
			'nonce' => wp_create_nonce('myajax-nonce')
		)
	);  

}

это название основного скрипта темы (см. выше), который подключается на сайте с помощью wp_enqueue_script().

Затем, в AJAX запросе добавим переменную с кодом nonce:

var ajaxdata = {
	action     : 'myajax-submit',
	nonce_code : myajax.nonce
};
jQuery.post( myajax.url, ajaxdata, function( response ) {
	alert( response );
});

Теперь, в обработке заброса необходимо проверить nonce код:

add_action( 'wp_ajax_nopriv_myajax-submit', 'myajax_submit' );
add_action( 'wp_ajax_myajax-submit', 'myajax_submit' );
function myajax_submit(){
	// проверяем nonce код, если проверка не пройдена прерываем обработку
	check_ajax_referer( 'myajax-nonce', 'nonce_code' );
	// или так
	if( ! wp_verify_nonce( $_POST, 'myajax-nonce' ) ) die( 'Stop!');

	// обрабатываем данные и возвращаем
	echo 'Возвращаемые данные';

	// не забываем завершать PHP
	wp_die();
}

check_ajax_referer() работает на основе функции wp_verify_nonce() и по сути является её оберткой для AJAX запросов.

Обратите внимание, что в данном случае Nonce код создается в HTML коде. А это значит, что если у вас установлен плагин страничного кэширования, то этот код может и наверняка будет устаревать к моменту очередного AJAX запроса, потому что HTML код кэшируется..

2. Проверка прав доступа

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

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

add_action( 'wp_ajax_nopriv_myajax-submit', 'myajax_submit' );
add_action( 'wp_ajax_myajax-submit', 'myajax_submit' );
function myajax_submit(){
	// проверяем nonce код, если проверка не пройдена прерываем обработку
	check_ajax_referer( 'myajax-nonce', 'nonce_code' );

	// текущий пользователь не имеет права автора или выше
	if( ! current_user_can('publish_posts') )
		die('Этот запрос доступен пользователям с правом автора или выше.')

	// ОК. У юзера есть нужные права!

	// Делаем что нужно и выводим данные на экран, чтобы вернуть их скрипту

	// Не забываем выходить
	wp_die();
}

Создание асинхронного AJAX запроса (метод POST)

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

HTML:

<!DOCTYPE html>
<html lang="ru">
<head>
  <meta charset="utf-8">
  <title>Пример работы AJAX</title>
</head>
<body>
  <h1>Пример работы AJAX</h1>

  <div id="welcome">
    <label for="name">Имя:</label>
    <input type="text" id="name" placeholder="Например, Иван">
    <button id="send">Отправить</button>
  </div>

<script>
//после загрузки DOM-дерева страницы
document.addEventListener("DOMContentLoaded",function() {
  //получить кнопку
  var mybutton = document.getElementById('send');
  //подписаться на событие click по кнопке и назначить обработчик, который будет выполнять действия, указанные в безымянной функции
  mybutton.addEventListener("click", function(){
    //1. Сбор данных, необходимых для выполнения запроса на сервере
    var name = document.getElementById('name').value;
    //Подготовка данных для отправки на сервер
    //т.е. кодирование с помощью метода encodeURIComponent
    name = 'nameUser=' + encodeURIComponent(name);
    // 2. Создание переменной request
    var request = new XMLHttpRequest();
    // 3. Настройка запроса
    request.open('POST','processing.php',true);
    // 4. Подписка на событие onreadystatechange и обработка его с помощью анонимной функции
    request.addEventListener('readystatechange', function() {
      //если запрос пришёл и статус запроса 200 (OK)
      if ((request.readyState==4) && (request.status==200)) {
        // например, выведем объект XHR в консоль браузера
        console.log(request);
        // и ответ (текст), пришедший с сервера в окне alert
        console.log(request.responseText);
        // получить элемент c id = welcome
        var welcome = document.getElementById('welcome');
        // заменить содержимое элемента ответом, пришедшим с сервера
        welcome.innerHTML = request.responseText;
      }
    });
    // Устанавливаем заголовок Content-Type(обязательно для метода POST). Он предназначен для указания кодировки, с помощью которой зашифрован запрос. Это необходимо для того, чтобы сервер знал как его раскодировать.
    request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
    // 5. Отправка запроса на сервер. В качестве параметра указываем данные, которые необходимо передать (необходимо для POST)
    request.send(name);
  });
});
</script>

</body>
</html>

PHP:

<?php
// создадим переменную для формирования ответа
$output ='';
// если в массиве пост есть ключ nameUser, то
if (isset($_POST)) {
  // в переменную name помещаем переданное с помощью запроса имя
  $name = $_POST;
  // добавляем в переменную output строку приветствия с именем
  $output .= 'Здравствуйте, '.$name.'! ';
  // добавляем в переменную output IP-адрес пользователя
  if ($_SERVER) {
    $output .= 'Ваш IP адрес: '. $_SERVER;
  }
  else {
   $output .= 'Ваш IP адрес неизвестен.';
  }
  // выводим ответ
  echo $output;
}

Создание асинхронного AJAX запроса (метод GET)

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

Для этого необходимо создать на сервере 2 файла в одном каталоге:

  1. – HTML-страница, которая будет отображаться пользователю. В этой же страницы поместим
    скрипт, который будет осуществлять все необходимые действия для работы AJAX на стороне клиента.
  2. – PHP-файл, который будет обрабатывать запрос на стороне сервера, и формировать ответ.
    Начнём разработку с создания основной структуры файла
<!DOCTYPE html>
<html lang="ru">
<head>
  <meta charset="utf-8">
  <title>Пример работы AJAX</title>
</head>
<body>
  <h1>Пример работы AJAX</h1>
  <div id="welcome"></div>
  <script>
  // Здесь поместим код JavaScript, который будет отправлять запрос на сервер, получать его и обновлять содержимое страницы. Всё это будет работать без перезагрузки страницы

</script>
</body>
</html>  

Рассмотрим последовательность действий, которые необходимо выполнить на стороне клиента (в коде JavaScript):

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

  2. Создадим переменную, которая будет содержать экземпляр объекта XHR (XMLHttpRequest).

  3. Настроим запрос с помощью метода .

    Указываются следующие параметры:

    • Метод, с помощью которого будет посылаться запрос на сервер (GET, POST).
    • URL-адрес, который будет обрабатывать запрос на сервере.
    • Тип запроса: синхронный (false) или асинхронный (true).
    • Имя и пароль при необходимости.
  4. Подпишемся на событие объекта XHR и укажем обработчик в виде анонимной или
    именованной функции. После этого создадим код внутри этой функции, который будет проверять состояние ответа, и
    выполнять определённые действия на странице. Ответ, который приходит с сервера, всегда находится в свойстве
    .

    Дополнительно с проверкой значения свойства числу 4, можно проверять и значение свойства
    . Данное свойство определяет статус запроса. Если оно равно 200, то всё . А
    иначе произошла ошибка (например, 404 – URL не найден).

  5. Отправим запрос на сервер с помощью метода .

    Если используем для отправки запроса метод GET, то передавать данные в параметр данного метода не надо. Они
    передаются в составе URL.

    Если используем для отправки запроса метод POST, то данные необходимо передать в качестве параметра методу
    . Кроме этого, перед вызовом данного метода необходимо установить заголовок Content-Type, чтобы
    сервер знал в какой кодировке пришёл к нему запрос и смог его расшифровать.

Содержимое элемента :

// 2. Создание переменной request
var request = new XMLHttpRequest();
// 3. Настройка запроса
request.open('GET','processing.php',true);
// 4. Подписка на событие onreadystatechange и обработка его с помощью анонимной функции
request.addEventListener('readystatechange', function() {
  // если состояния запроса 4 и статус запроса 200 (OK)
  if ((request.readyState==4) && (request.status==200)) {
    // например, выведем объект XHR в консоль браузера
    console.log(request);
    // и ответ (текст), пришедший с сервера в окне alert
    console.log(request.responseText);
    // получить элемент c id = welcome
    var welcome = document.getElementById('welcome');
    // заменить содержимое элемента ответом, пришедшим с сервера
    welcome.innerHTML = request.responseText;
  }
}); 
// 5. Отправка запроса на сервер
request.send();

В итоге файл будет иметь следующий код:

<!DOCTYPE html>
<html lang="ru">
<head>
  <meta charset="utf-8">
  <title>Пример работы AJAX</title>
</head>
<body>
  <h1>Пример работы AJAX</h1>

  <div id="welcome"></div>

<script>
window.addEventListener("load",function() {
  var request = new XMLHttpRequest();
  request.open('GET','processing.php',true);
  request.addEventListener('readystatechange', function() {
    if ((request.readyState==4) && (request.status==200)) {
      var welcome = document.getElementById('welcome');
      welcome.innerHTML = request.responseText;
    }
  });
request.send();
});
</script>

</body>
</html>

На сервере (с помощью php):

  1. Получим данные. Если данные посланы через метод , то из глобального массива
    . А если данные переданы с помощью метода , то из глобального
    массива .
  2. Используя эти данные, выполним некоторые действия на сервере. В результате которых получим некоторый ответ.
    Выведем его с помощью .
<?php
$output = 'Здравствуйте, пользователь! ';
if ($_SERVER) {
  $output .= 'Ваш IP адрес: '. $_SERVER;
}
else {
 $output .= 'Ваш IP адрес неизвестен.';
}
echo $output;

Логичное подключение AJAX хуков

Я не стал усложнять чтение и не говорил, как правильно подключать AJAX через хуки в коде. Впрочем все что написано ниже не обязательно, потому что работать будет и так, но это рекомендуется.

Функции обработчики установленные хукам:

  • wp_ajax_(action)
  • wp_ajax_nopriv_(action) 

Оба хука всегда удовлетворяют условию wp_doing_ajax():

if( wp_doing_ajax() ){}

// до версии WP 4.7 
if( defined('DOING_AJAX') ){}

А значит сами хуки нужно подключать, только если срабатывает это условие.

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

Пример того, как рекомендуется подключать все AJAX хуки.

// подключаем AJAX обработчики, только когда в этом есть смысл
if( wp_doing_ajax() ){
	add_action('wp_ajax_myaction', 'ajax_handler');
	add_action('wp_ajax_nopriv_myaction', 'ajax_handler');
}

// или так до WP 4.7
if( defined('DOING_AJAX') ){
	add_action('wp_ajax_myaction', 'ajax_handler');
	add_action('wp_ajax_nopriv_myaction', 'ajax_handler');
}

В этом случае хуки будут подключены только во время AJAX запроса и не будут подключены при простом посещении фронта, админки, REST или CRON запросе.

Напомню также, что данные отправляемые с фронтэнда на файл wp-admin/admin-ajax.php обработаются указанной в хуке произвольной функцией ajax_handler(), независимо авторизован пользователь или нет.

2 AJAX POST Example, the jQuery way

So let’s get our hands dirty. Here’s our HTML5 and jQuery:

Let’s break down the not-so-clear parts of the method. The setting controls how data we receive from the server is treated. So if we want JSON from the server to be treated as text in our Javascript on the client side, for example, then we set this value as . If we don’t set the value at all, jQuery will try to figure out what the server sent and convert it intelligently. If it thinks it’s JSON, it’ll turn it into a JavaScript object; if it thinks it XML it’ll turn it into a native XMLDocument JavaScript object, and so on.

Next up is , which is the HTTP verb that we want to use. I’ll let you in on a little secret: since jQuery 1.9.0, you can use instead of . It could make things a little bit clearer for newcomers.

Following is . This is where understanding how HTTP requests and responses work helps a lot. What we set here gets sent as part of the HTTP header field . That’s important to note because we’re letting the server know ahead of time what type of content we’re sending, which allows the server to interpret the response correctly. For example, if you see a of you would know to process the content as JSON in your server-side code — it’s as simple as that.

Now, the setting is the data we’re going to send to the server. We can send data to the server in a variety of different formats, but the default is . That means we’ll be sending text to our server with our form data formatted in key-value pairs, like . Most, if not all, web server languages will pick up the key-value pairs and separate them for you either natively or through the use of libraries or frameworks.

Here’s how to do that in a few different languages:

  • Ruby with Sinatra
  • Python with web.py
  • Node.JS with Express and body-parser middleware

Most POST requests from a form will use the content type. I’ll also provide an alternative if you need to POST actual JSON from jQuery — if, for instance, you need to make a call to your own RESTful API.

The method has several events we can hook into to handle our AJAX responses accordingly: , , , and . The ones we care about most are and , so we’ll use these in our example.

One important thing to note is that the data parameter for the function will be dependent on the setting. So it’s completely possible to treat JSON coming from the server as a string by setting to . Many developers, including myself, occasionally get tripped up attempting to output their request in the method and then wonder why nothing is showing up when they try to render JSON as HTML, which doesn’t work at all.

As long as you know that the parameter can be transformed into a different data type, fixing that problem will be easy. If your AJAX server responses for the form will always be of one type — for instance, JSON — and you will always treat it as JSON, then it makes sense to set to . If you need to juggle between different data types, omit to allow jQuery to intelligently convert the data.

Our function is where we do things after we get a successful AJAX response, like updating a message in our page or search results in a table. Here is a good live example of jQuery AJAX and POST from one of my clients, a free keyword suggestion tool for advanced SEO marketers.

Now, on to the server side. From the client side, all we need to worry about is sending the right Content Type and Request body (the content we send along like the form data). On the server side we pick this up, process it, and respond accordingly.

It’s important to note that we need to format the response data correctly according to the we want to send back. If we want to send a simple text message we would respond with . If we want to respond with JSON, we’ll send a and a properly formatted JSON string without any extra characters before or after the string, like so:

This will allow jQuery to convert the string into JSON. Please do not try to build a JSON string manually; use your language’s built-in JSON function or libraries to do it for you. Trust me, it will save you time and headaches.

2.1 Server side code for our AJAX form

If you’re running PHP 5.4 or above, you can fire up a server by going into your terminal running the following commands:

If you’re on Mac, install Mac Ports and then php55 with:

Then run the development server:

Now open up your browser to http://localhost:8111.

1 Introduction

You load a website and you see something. You click on a button — maybe «next page» to change the result set — and it loads new data, but the page didn’t refresh. This happened thanks to AJAX.

Let’s look at a real-life example. Go to google.com and search for «dogs» — see how the search results appear instantly, and they even change when you alter the search? That data got pulled in «on-demand,» and that’s what AJAX is. AJAX relies on both JavaScript and HTTP, and it’s good to understand both in order to completely grasp AJAX.

1.1 What is HTTP?

What you see when you browse a page is not just one big object. It’s actually made up of multiple pieces that are pulled together behind the scenes, in several different HTTP requests. This video gives a good overview of HTTP.

HTTP is like an annoying kid that always has something to say back to you. We make requests like «I want the search results for the ‘dog’ keyword.» Every request has a response; if everything went OK, we would get back an HTTP Status code of 200, or . If something went wrong, it usually returns one of several errors in the 400s and 500s, depending on the problem. Every request includes the data that we send along with additional information, contained in header fields, describing what we want and how we want it. The same goes for the response.

HTTP uses verbs to describe actions like getting, creating, updating, and deleting. The verb is usually used to create resources, and that’s the one we’ll use in our example.

1.2 How do I see my requests?

There are several tools that will allow you to see all of the individual requests, and most can be added to your web browser or already come built right in.

Firefox includes the built-in Firefox Inspector, which you can access with the shortcut or . HTTP requests appear under the Network tab. There’s also Firebug for Firefox — which you can download here — and open using the or shortcut; HTTP requests can be found in the Net tab.

Safari, Chrome, and Internet Explorer also have built-in developer toolbars. Both Chrome and IE have a Network tab, while requests are shown under Safari’s Timelines tab. We’ll be using the Firefox Inspector, which by default shows every request including JavaScript, CSS, Images, and XHR. The inspector only shows requests made while it’s open, so you’ll need to refresh the page to capture them the first time.

1.3 XHR, is that a virus or something?

No. You won’t be suffering from a venereal disease, I promise. Browsers use a special JavaScript object called the to make HTTP requests in the background. You can think of it as your personal assistant that gets things for you and puts them where they’re supposed to be once you give them instructions. With jQuery you don’t have to worry about learning how to use this object, because the framework has taken care of all of the nitty-gritty details for you.

1.4 Why should I care?

If you know how to put together the pieces, you’ll be able to handle any AJAX situation. You could hop into another framework like Dojo, or even understand the AJAX parts of AngularJS.

Just as the HTML page from our mental model above was a single GET request, we could do the same with other types of requests. We could modify data on our server using POST, PUT, PATCH or DELETE, for example.

Отлавливаем баги, PHP ошибки

Проблемы могут возникнуть при AJAX запросе и появлении ошибок PHP. Заметки или сообщения могут изменить возвращаемый результат или вызвать ошибку javascript.

Дебаг (вывод ошибок на экран)

Вариант:

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

При этом в коде можно использовать привычные функции print_r() или var_dump(), чтобы увидеть что находится в нужных переменных.

Вариант: включаем показ ошибок в AJAX запросах

WordPress по умолчанию не показывает ошибки для AJAX запросов даже если константа WP_DEBUG включена! Видно это в коде функции wp_debug_mode().

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

Чтобы включить показ ошибок при AJAX запроса, нужно вставить такой код в файл темы functions.php или в плагин. Но лучшее его вставить как можно раньше, чтобы видеть ранние ошибки, лучше всего в MU плагины…

if( WP_DEBUG && WP_DEBUG_DISPLAY && (defined('DOING_AJAX') && DOING_AJAX) ){
	@ ini_set( 'display_errors', 1 );
}

Вариант: вывод данных в лог файл

Если по ходу написания кода нужно заглянуть в переменную $myvar, то еще можно использовать такой код в обработчике ajax запроса:

error_log( print_r($myvar, true) );

В результате, в файл логов сервера (error.log) будет записано содержимое переменной $myvar. Так можно выполнить ajax, и заглянуть в лог.

Вариант: вывод PHP ошибок в лог файл

Чтобы выводить PHP заметки и ошибки в лог файл, нужно включить константу WP_DEBUG_LOG. Такой лог файл появится в папке wp-content.

Вариант:

Если не получается увидеть сообщение об ошибке и нужно работать в режиме разработчика, можно очистить буфер сразу перед возвратом данных:

ob_clean();
echo $whatever;
die();

После этого нужно посмотреть что возвращает запрос через дебаг браузера или как-то еще…

Вариант:

Ошибка при возвращении данных

Если AJAX запрос на в файл провалился, то будет возвращен ответ или .

  • — ошибка при проверке запроса. См. функцию check_ajax_referer()
  • — обработка запроса вернула пустой результат
  • — также возвращается по умолчанию во всех остальных случаях.

JS Учебник

JS ГлавнаяJS ВведениеJS УстановкаJS ВыводJS СинтаксисJS ЗаявленияJS КомментарииJS ПеременныеJS ОператорыJS АрифметикаJS ПрисваиванияJS Типы данныхJS ФункцииJS ОбъектыJS ОбластьJS СобытияJS СтрокиJS Методы строкJS ЧислаJS Методы чиселJS МассивыJS Методы массиваJS Сортировка массиваJS Итерация массиваJS ДатыJS Формат датыJS Метод получения датJS Методы набора…JS Математические…JS Случайные числаJS БулевыJS Сравнение…JS Заявления if…elseJS Заявление switchJS Цикл forJS Цикл whileJS Заявление break…JS Преобразование…JS Битовые…JS Регулярные выраженияJS ОшибкиJS ОтладчикJS ПодъемныйJS СтрогийJS Ключевое слово thisJS Руководство стиляJS ПрактикаJS Распространенные ошибкиJS ЭффективностьJS Зарезервированные словаJS ВерсииJS Версия ES5JS Версия ES6JS JSON

Отправка изображения или файла ajax-запросом через jQuery

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

html-код будет такой:

<button id="addfile"><span>Загрузить изображение</span><input type="file" id="load_file" value=""></button>

css код:

#addfile {
  position: relative;
  overflow: hidden;
  width: 180px;
  height: 34px;
}
#load_file {
  position: absolute;
  top: 0;
  left: 0;
  width: 180px;
  height: 34px;
  font-size: 0px;
  opacity: 0;
  filter: alpha(opacity:0);
}
#load_file:hover {
  cursor: pointer;
}

Суть идеи в том, что поверх кнопки выводится стандартный input для выбора файла, но он полностью прозрачен и имеет такие же размеры как кнопка. Таким образом, пользователь видит кнопку button, но когда наводит на нее курсор, фактически наводит на input. Соответственно, когда он нажимает на кнопку, на самом деле нажимается input выбора файла. Для того, чтобы не мигал курсор после выбора файла, размер шрифта задан 0px.

Теперь javascript код отправки файла на сервер с отображением прогресса:

$(function() {
  $('#load_file').on('change', loadfile);
});

function loadfile() {
  $('#addfile span').html('Загружено 0 %');
  files = $('#load_file').files;
  var form = new FormData();
  form.append('upload', files);
  $.ajax({
    url: '<url-адрес>',
    type: 'POST',
    data: form,
    cache: false,
    processData: false,
    contentType: false,
    xhr: function() {
      var myXhr = $.ajaxSettings.xhr();
      if (myXhr.upload) {
        myXhr.upload.addEventListener('progress',ShowProgress, false);
      }
      return myXhr;
    },
    complete: function(data){
      $('#addfile span').html('Загрузить изображение');
      $('#load_file').val('');
    },
    success: function(message){
      alert(message);
    },
    error: function(jqXHR, textStatus, errorThrown) {
      alert(textStatus+' '+errorThrown);
    }
  });
}

function ShowProgress(e) {
  if(e.lengthComputable){
    $('#addfile span').html('Загружено '+Math.round(100*e.loaded/e.total)+' %');
  }
}

При загрузке файла на сервер в кнопке будет показываться сколько % уже передано на сервер. После завершения загрузки название кнопки возвращается как было, а значение input-а с файлом устанавливается пустым, чтобы можно было снова выбирать новый файл.

Пример серверной части на php (по просьбе Евгения):

  $message = '';
  if (empty($_FILES) || $_FILES == "none") {
    $message = 'Вы не выбрали файл';
  } else if ($_FILES == 0 || $_FILES > 9437184) {
    $message = 'Размер файла не соответствует нормам (максимум 9 Мб)';
  } else if (($_FILES != 'image/jpeg') && ($_FILES != 'image/pjpeg') &&
             ($_FILES != 'image/gif') && ($_FILES != 'image/png')) {
    $message = 'Допускается загрузка только картинок JPG, GIF и PNG.';
  } else if (!is_uploaded_file($_FILES)) {
    $message = 'Что-то пошло не так. Попытайтесь загрузить файл ещё раз.';
  } else {
    $ftype = $_FILES;
    $fname = 'newname_image.'.($ftype == 'image/gif' ? 'gif' : ($ftype == 'image/png' ? 'png' : 'jpg'));
    if (move_uploaded_file($_FILES, $_SERVER.'/files/'.$fname)) {
      $message = 'Изображение успешно загружено.';
    } else {
      $message = 'Что-то пошло не так. Попытайтесь загрузить файл ещё раз.';
    }
  }
  exit($message);

Информация о загруженном изображении будет содержаться в $_FILES, т.к. скриптом файл добавлялся так: form.append(‘upload’, files); Соответственно, всё что требуется от php-программы — это проверить что файл соответствует ожидаемым параметрам, перенести файл в нужную папку (в примере в папку files) под нужным именем (в примере newname_image) и вернуть в браузер ответ, который в моем примере просто выводится пользователю командой alert(message);

jQuery.post( url [, data ] [, success ] [, dataType ] )Возвращает: jqXHR

Описание: Загружает данные с сервера при помощи HTTP POST запроса.

    • url
      Тип:

      Строка с URL адресом, на который будет отправлен запрос.

    • data
      Тип: или

      Объект или строка, которые будут отправлены на сервер вместе с запросом.

    • success
      Тип: ( data, textStatus, jqXHR )
      Функция обратного вызова, которая выполняется если запрос успешно завершается. Требуется если указан аргумент , но может быть задан как в таком случае.
    • dataType
      Тип:

      Тип данных ожидаемый от сервера. По умолчанию: распознается по полю Content-Type заголовка ответа сервера, поддерживаются: xml, json, script, text, html.

  • Ассоциативный массив с настройками Ajax запроса. Все параметры опциональны, исключая url. Значения по умолчанию могут быть установлены при помощи метода $.ajaxSetup(). Смотрите подробнее описание всех возможных параметров на странице jQuery.ajax( settings ). Тип запроса автоматически будет установлен в значение POST.

Это сокращенная Ajax функция, которая эквивалентна следующему коду:

1
2
3
4
5
6
7

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

Начиная с jQuery 1.5, в функцию также передается (в jQuery 1.4 и ранее, передавался объект ).

В большинстве случаев обработчик success указывают:

1
2
3

В это примере полученный из запроса HTML код вставляется в элемент на странице.

Страницы запрошенные при помощи никогда не кэшируются, поэтому опции и в не будут иметь никакого эффекта для таких запросов.

Объект jqXHR

Начиная с jQuery 1.5, все Ajax методы jQuery возвращают объект . Объект jQuery XHR или «jqXHR,» возвращается реализацией интерфейса Promise и предоставляет все его свойства, меоды и повередени Promise в целом (смотрите Deferred object для справки). Методы (успех), (ошибка), and (для гарантированного обработчика, не зависимо от успеха или ошибки ответа, добавлен в версии jQuery 1.6) принимают функцию, которая вызывается когда запрос завершается. Аргументы этих функция описаны на странице в разделе справки.

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

Уведомление об устаревании

Функции обратного вызова , , and удалены в jQuery 3.0. Используйте методы , и вместо них.

  • Если запрос jQuery.post() возвращает код ошибки, то он будет выполнен тихо, до тех пор пока не будет вызван глобальный .ajaxError() метод. В качестве альтернативы, начина с jQuery 1.5, метод в объекте возвращаемый jQuery.post() также доступен для обработки ошибок.
Добавить комментарий

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

Adblock
detector