CoderNotes - заметки программиста

Публикации  »  JavaScript + jQuery
Скидка 65% на Skillbox

Получите скидку 65% на любой курс программирования на популярной образовательной платформе Skillbox!

Подробнее
Бесплатный хостинг + SSL-сертификат

Зарегистрируйте домен и получите 2 месяца бесплатного хостинга и SSL-сертификат на 1 год в подарок

Подробнее

Ajax-запрос к серверу через jQuery

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

 

Запрос html-данных с помощью функции Load

Это самый простой ajax-запрос через jQuery с получением html-данных и их вставкой в dom-элемент с id="result" (содержимое элемента заменяется):

$('#result').load('<url-адрес>');

Более продвинутый вариант использования load:

$('#result').load('<url-адрес>', {par1:val1, par2:val2, ...}, function(response, status, xhr) {
  if (status == 'success') {
    alert('Готово');
  } else {
    alert('Ошибка: ' + xhr.status + ' ' + xhr.statusText);
  }
});

В этом примере серверу так же передаются параметры, а после получения ответа проверяется не было ли ошибки (например, ответ от сервера не был получен) и выполнение различных действий.

 

Ajax-запросы функциями GET и POST

Эти функции осуществляют отправку ajax запроса http-методами get и post. Приведу пару примеров их использования.

$.get(
  '<url-адрес>',          // адрес отправки запроса
  {par1:val1, par2:val2, ...},  // передача с запросом каких-нибудь данных
  function(data) {              
    // какие-то действия с полученными от сервера данными data
  }
);

Передача данных не обязательна, как и выполнение каких-либо действий после получения ответа от сервера, т.е. в этом случае, строчки 3 и 4-6 можно удалить при необходимости и таким образом еще сократить код.

Тип получаемых от сервера данных можно указать, добавив dataType (см.ниже) - по-умолчанию определяется автоматически.

Использование post аналогично, но в следующем примере использую вызов функции после получения ответа от сервера.

$.post(
  '<url-адрес>',
  {par1:val1, par2:val2, ...},
  onSuccess
);

function onSuccess(data) {
  // какие-то действия с полученными от сервера данными data
}

На самом деле, функции get и post являются сокращенными вариантами функции ajax, которую рассмотрю ниже.

 

Получение json-данных с помощью getJSON

getJSON - укороченный вариант ajax-запроса методом GET и получением данных в виде json. Способ удобен, например, для получения какого-то массива с данными и последующей работы с ним.

$.getJSON('<url-адрес>', {par1:val1, par2:val2, ...}).done(function(data) {
  // что-то делаем с данными, например, обходим их в цикле и выводим:
  for (var i=0; i<data.length; i++) {
    console.log(data[i].text);
  }
}).error(function(xhr, textStatus, errorThrown) {
  alert('Ошибка: ' + textStatus+' '+errorThrown);
});

На стороне сервера программа формирует массив и преобразовывает его в json-строку, например, так:

$arr = array();
$arr[0] = array('id' => 10, 'text' => 'тестовая строка 1');
$arr[1] = array('id' => 20, 'text' => 'тестовая строка 2');
$arr[2] = array('id' => 30, 'text' => 'тестовая строка 3');
echo json_encode($arr);

Точно так же можно передать с сервера и объекты stdClass, преобразовав их в json-строку.

Другой вариант записи успешной и не успешной обработки getJSON:

$.getJSON('<url-адрес>', function(data) {
  // что-то делаем с данными
}).fail(function(xhr, textStatus, errorThrown) {
  alert('Ошибка: ' + textStatus+' '+errorThrown);
});
 

Простой ajax-запрос через jQuery с помощью функции AJAX

Теперь приведу пример простого get запроса функцией ajax и получением html-данных.

$.ajax({
  url: '<url-адрес>',
  dataType: 'html',
  success: function(data) {
    // какие-то действия с полученными данными data
  }
});

Запрос к серверу происходит get-методом, т.к. параметр, отвечающий за тип запроса, type по-умолчанию равен GET.

 

Более сложный пример ajax-запроса через jQuery

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

$.ajax({
  url: '<url-адрес>',
  type: 'post',
  data: '<отправляемые_данные>', // можно строкой, а можно, например, так: $('input[type="text"], input[type="radio"]:checked, input[type="checkbox"]:checked, select, textarea')
  dataType: 'json',
  beforeSend: function() {
    $('#sendajax').button('loading');
  },
  complete: function() {
    $('#sendajax').button('reset');
  },
  success: function(json) {
    // какие-то действия с полученными данными
  },
  error: function(xhr, ajaxOptions, thrownError) {
    alert(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText);
  }
});

Кнопка отправки данных:

<button class="btn btn-primary" data-loading-text="Отправка..." id="sendajax" type="button">Отправить</button>

В приведенном примере при нажатии на кнопку button, сначала меняется состояние кнопки (текст на ней меняется на "Отправка..." и она становится не активной), что делается при помощи параметра beforeSend. Затем происходит отправка запроса с передачей нужных данных. После того, как получен ответ от сервера состояние кнопки возвращается в прежнее (текст меняется на "Отправить", становится активной). Ответ получается в виде json-данных.

Коротко опишу параметры отправки ajax-запроса, которые чаще всего могут пригодиться:

url Адрес отправки ajax-запроса
type Способ отправки запроса GET или POST
data Отправляемые серверу данные. Может быть строка с параметрами и их значениями в формате par1=val1&par2=val2&..., объект jQuery, например, $('input[type="text"]') или другие данные.
dataType Тип получаемых от сервера данных. Может быть html, json, text, script и xml.
cache Кэширование браузером запроса (false - не кэшировать).
async Асинхронное выполнение запроса, т.е. программа продолжает выполняться не дожидаясь ответа сервера. Если указать false, то запрос будет выполнен синхронно, при этом страница не будет ни на что реагировать, пока не будет получен ответ от сервера.
processData Преобразование отправляемых данных в url-формат. Если нужно чтобы данные не преобразовывались, установить в false. Например, при отправке изображения на сервер или xml-данных.
contentType Тип передаваемых данных, по умолчанию "application/x-www-form-urlencoded; charset=UTF-8". Если указать false, то в заголовке не будет передаваться тип, что может быть необходимо, например, при отправке изображения на сервер.
beforeSend Функция, выполняемая перед отправкой ajax-запроса.
complete Функция, выполняемая после получения ответа от сервера (любого, успешного или нет).
success Функция, выполняемая при удачном выполнении запроса.
error Функция, выполняемая в случае ошибки.

Ниже приведу еще несколько примеров использования ajax-запросов.

 

Отправка формы со всеми данными ajax-запросом через jQuery

Примерный код html-формы:

<form id="myform" action="" method="POST">
  <label for="user_name">Ваше имя:</label>
  <input name="user_name" value="" type="text" />
  <input type="submit" value="Отправить">
</form>

JavaScript код:

$('#myform').submit(function(e) {
  e.preventDefault();
  $.ajax({
    type: $(this).attr('method'),
    url: '<url-адрес>',
    data: $(this).serialize(),
    async: false,
    dataType: "html",
    success: function(result){
      alert('Форма отправлена');
    }
  });
});

Для того чтобы страница не перезагружалась при нажатии на кнопку "submit", сначала отменяем стандартые действия браузера использовав e.preventDefaults().

В параметре data мы передаем все поля формы использовав $(this).serialize() - эта функция преобразует все input-ы и select-ы в строку, пригодную для отправки на сервер.

Так же, здесь использован параметр async: false, чтобы пока форма не отправится на сервер больше ничего нельзя было нажать или сделать.

 

Отправка изображения или файла 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')[0].files;
  var form = new FormData();
  form.append('upload', files[0]);
  $.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['upload']['name']) || $_FILES['upload'] == "none") {
    $message = 'Вы не выбрали файл';
  } else if ($_FILES['upload']['size'] == 0 || $_FILES['upload']['size'] > 9437184) {
    $message = 'Размер файла не соответствует нормам (максимум 9 Мб)';
  } else if (($_FILES['upload']['type'] != 'image/jpeg') && ($_FILES['upload']['type'] != 'image/pjpeg') &&
             ($_FILES['upload']['type'] != 'image/gif') && ($_FILES['upload']['type'] != 'image/png')) {
    $message = 'Допускается загрузка только картинок JPG, GIF и PNG.';
  } else if (!is_uploaded_file($_FILES['upload']['tmp_name'])) {
    $message = 'Что-то пошло не так. Попытайтесь загрузить файл ещё раз.';
  } else {
    $ftype = $_FILES['upload']['type'];
    $fname = 'newname_image.'.($ftype == 'image/gif' ? 'gif' : ($ftype == 'image/png' ? 'png' : 'jpg'));
    if (move_uploaded_file($_FILES['upload']['tmp_name'], $_SERVER['DOCUMENT_ROOT'].'/files/'.$fname)) {
      $message = 'Изображение успешно загружено.';
    } else {
      $message = 'Что-то пошло не так. Попытайтесь загрузить файл ещё раз.';
    }
  }
  exit($message);

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

Кстати, реализовать выбор файла по нажатию на кнопку или произвольный элемент на странице можно еще другим способом. Его суть в том, что при нажатии на элемент нужно добавить на страницу форму для отправки изображения с input type="file" и эмулировать нажатие на него.

Допустим, есть кнопка:

<button id="add_image" class="btn btn-default">Загрузить изображение</button>

Теперь, при нажатии на нее добавим форму и кликнем на input type="file", а затем отправим форму на сервер:

$(document).ready(function() {
  $('#add_image').on('click', function(e) {
    e.preventDefault();
    $('body').prepend('<form enctype="multipart/form-data" id="form-upload-img" style="display: none;"><input type="file" name="file" /></form>');
    $('#form-upload-img input').on('input',function(e){
      $.ajax({
        url: 'upload_image.php',
        type: 'post',
        dataType: 'json',
        data: new FormData($('#form-upload-img')[0]),
        cache: false,
        contentType: false,
        processData: false,
        success: function(json) {
          alert('Файл загружен на сервер');
        },
        error: function(xhr, ajaxOptions, thrownError) {
          alert(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText);
        }
      });
    });
    $('#form-upload-img input[name=\'file\']').trigger('click');
    $('#form-upload-img').remove();
  });
});

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

 

Категория: JavaScript + jQuery

Книги по теме:

Посмотреть все книги по программированию

Комментарии к статье:

04.12.17   Гость Спасибо. Всё что нужно про ajax в одной статье.
18.03.18   Гость ОШИБКА в строке 2
$('#load_file').on('change', loadfile);
должно быть так -
$('#load_file').on('change', function loadfile());
20.03.18   Гость Правильно: $('#load_file').on('change', loadfile); где loadfile - это имя функции-обработчика
12.06.18   Гость а на стороне сервера как принять то(((
12.06.18   Гость POST GET понятно, а что делать с load.
12.06.18   Гость На стороне сервера php программа может получить данные (если они передавались) с помощью $_GET (если был get-запрос), $_POST (если был post-запрос) или $_REQUEST (любой запрос). Затем php программа на стороне сервера формирует ответ, в простейшем случае, просто html-код, или другой, который определяется параметром dataType.
Например, если используется
$('#result').load('<url-адрес>');
тогда php-программа может к примеру быть такой:
echo "<p style='color:green'><b>Test</b></p>";
Все что выводится командами echo окажется вставленным в #result. В данном случае, параметр dataType будет считаться равным значению "html". Другие варианты передаваемых php-программой данных рассмотрены выше в статье.
01.09.18   Гость А как записать данные, полученные от сервера, в переменную, но в асинхронном режиме?
09.09.18   Гость указать параметр async = true, например, так:
var p = ''; // переменная, в которую нужно будет записать ответ от сервера
$.ajax({
  url: '<url-адрес>',
  async: true,  // асинхронный режим
  success: function(data) {
    p = data; // записываем в переменную данные от сервера
  }
});
вот и всё
12.10.18   Евгений Есть пример серверной стороны для последнего примера?
12.10.18   Администратор Спасибо за вопрос. Добавил в статью пример серверной части на php.
13.10.18   Евгений Это тебе спасибо) как раз то что нужно) слушай, с тобой в вк связаться можно? Пару вопросов есть)
13.10.18   Администратор Лучше написать на e-mail
18.10.18   Юрий Если на серверной стороне это функция в файле.
Допустим наш файл это ajax.php
В файле есть:
fuction func1()
fuction fnuc2()
fuction setFile()

как составить запрос к функции setFile?
18.10.18   Гость ajax-запрос делается по какому-то url, значит, в нем нужно указать такой адрес, чтобы php-скрипту было понятно, что нужно вызвать нужную функцию. Например, url: 'ajax.php?func=setFile', соответственно, первые строки в ajax.php должны прочитать get-переменную func и вызвать соответствующую функцию.
17.08.19   Владимир Все по существу, без воды, все понятно. Отлично! Огромное спасибо!
12.01.20   Гость Коротко и все понятно. Автору лайк.
01.07.20   Natalia Здравствуйте! Понравился ваш сайт, тем что здесь все детально объясняется, (так как в ajax и jquery разбираюсь очень слабо). Скажите, а как можно с вами связаться? Хотела бы попросить вашей помощи. В моем коде, который пишу у себя на локальном сервере, видимо есть ошибка. Потому что данные полей формы, которые формируются динамически, не отправляются, а только первое поле и его значение. Остальное все где-то теряется.
15.04.21   Гость При выполнении данного кода.
var result = '';
$.ajax({
url: 'url-адресс',
method: 'POST',
async: true,
data:{this_card:1},
success: function(response){
var res = JSON.parse(response)['result'];
result = res;
}
});
console.log(result);
выдаёт пустое значение, которое мы вписали. как записать полученный массив?
14.11.22   Сергей Нормально. Работает.
"...всё что требуется от php-программы - это проверить что файл соответствует ожидаемым параметрам, перенести файл в нужную папку (в примере в папку files) под нужным именем (в примере newname_image) и вернуть в браузер ответ...", если бы php ещё прописывал в базу путь к файлу - было бы готовое решение.
14.11.22   Сергей P.S. Предыдущие загруженные файлы из папки удаляются! Где затык?
10.03.23   Кость рапр

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