AJAX основы
Пробежимся по статьям об AJAX на сайте dnzl.ru
(некоторые статьи морально устарели и содержат неточности перевода):
- Парсим JSON: «Преобразуем строку формата JSON в объект и наоборот»
/view_post.php?id=350.
Рассматриваются нативные методыJSON.parse()
иJSON.stringify( )
, а также метод jQuery$.parseJSON
. - «JSON для начинающих, с использованием javascript и jQuery»
/view_post.php?id=289
Основные моменты статьи:Массив, как и числа, в формате JSON не заключаются в кавычки.Рассматривается метод библиотекиjQuery $.getJSON
. - «Знакомство с укороченными Ajax методами jQuery»
/view_post.php?id=345
Рассматривается:Укороченные методыload()
,$.post()
, и$.get()
. Приведены примеры на codepen. - «Ajax запрос методом GET с примерами»
/view_post.php?id=283Рассматривается метод jQuery$.get()
. Приведен пример использования. - «Ajax запрос методом POST, пример с использованием json_encode»
/view_post.php?id=285
Рассматриваются методы PHPjson_decode()
иjson_encode()
.Приведен пример метода jQuery$.post()
.Рассмотрена сериализация формы$(this).serialize()
. - «Функция jQuerys $.ajax()»
/view_post.php?id=344Рассматривается:Метод jQuery$.ajax()
с кратким описанием всех параметров метода.Приведен пример создание запроса JSONP с целью получения информации от сервиса Joind.in. - «Метод jQuery getJSON»
/view_post.php?id=284
Рассматривается пример использования метода jQuery$.getJSON()
Другие статьи:
- Динамическая (ajax) загрузка контента с jcarousel
(/view_post.php?id=304) - Ajax слайдер (jQuery и PHP)
/view_post.php?id=273 - PHP и AJAX для начинающих на простом примере
/view_post.php?id=271Получаем адрес студента при помощи метода jQuery$.ajax
, по порядковому номеру студента и его имени. - Создаем прокручиваемый блок с динамическим контентом на AJAX
/view_post.php?id=274 - Ajax добавить и удалить данные из базы данных, используя jQuery и PHP
/view_post.php?id=272
Инструменты:
fiddler
Изучение технологий Ajax: https://vk.com/wall-54530371_60540
Заголовки ответа PHP:
PHP
header('Content-Type: text/javascript; charset=utf-8');
header('Content-Type: text/html; charset=utf-8');
jQuery load
http://dnzlru/demo/ajax/jquery_load.html
HTML
<div id="targetDiv"></div>
<button class="load">Загрузить</button>
<button class="clear">Очистить</button>
jQuery or Javascript
<script type="text/javascript">
$(function() {
$(".load").click(function() {
$("#targetDiv").load("testLoad.htm");
});
$(".clear").click(function() {
$("#targetDiv").empty();
});
});
</script>
Загружаем только нужные элементы
Загружаем только нужные элементы. Для этого после url делаем пробел и перечисляем через запятую необходимые элементы (селекторы): http://dnzlru/demo/ajax/jquery_load_selector.html
jQuery or Javascript
$(function() {
$(".load").click(function() {
$("#targetDiv").load("testLoad.htm h2,p:last", function(){ alert("Первый пошел"); });
});
$(".clear").click(function() {
$("#targetDiv").empty();
});
});
$.load, получаем ответ от сервера сформированный на основе отправленных ему данных
jQuery or Javascript
$(function() {
$(".load").click(function() {
$("#target").load("testLoad.php", {
name: "Константин",
age: "33"
},
function(responseText, textStatus, XMLHttpRequest) {
$("#targetInfo").html('textStatus = ' + textStatus +
'<br/>Свойство readyState объекта XMLHttpRequest: ' + XMLHttpRequest.readyState +
'<br/>Свойство status объекта XMLHttpRequest: ' + XMLHttpRequest.status);
});
});
$(".clear").click(function() {
$("#target, #targetInfo").empty();
});
});
PHP
header('Content-Type: text/html; charset=utf-8');
if($_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest') {
if($_POST) {
print 'Имя: ' . $_POST['name'] . ', возраст: ' . $_POST['age'] . ', время: ' . date('H:i:s', time());
}
}
$.get
Посылаем данные на сервер и вставляем ответ в нужный нам элемент
jQuery or Javascript
$(function() {
$(".load").click(function() {
$.get("testGet.php", {
name: "Константин",
age: "35"
},
function(data) {
$("div").text(data);
});
});
$(".clear").click(function() {
$("div").empty();
});
});
PHP
header('Content-Type: text/html; charset=utf-8');
if($_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest') {
if($_GET) {
print 'Имя: ' . $_GET['name'] . ', возраст: ' . $_GET['age'] . ', время: ' . date('H:i:s', time());
}
}
Метод jQuery $.getJSON
Загружаем JSON данные при помощи метода jQuery $.getJSON
jQuery or Javascript
$(".getJSON").click(function() {
$.getJSON("testGetJSON.php", function(data, textStatus, jqXHR) {
var items = [];
$.each(data, function(i, item) {
items.push(item.name + ': ' + item.phone);
});
$("div#target").html(items.join('
'));
});
});
PHP
header('Content-Type: text/html; charset=utf-8');
if($_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest') {
print '[{"name":"Боб","phone":"565-76-17"},
{"name":"Елена","phone":"511-77-77"},
{"name":"Адам","phone":"523-45-77"},
{"name":"Крис","phone":"578-66-99"}]';
}
Загружаем JSON данные при помощи метода jQuery $.getJSON
с другого домена
jQuery or Javascript
$(".getJSONP").click(function() {
$.getJSON("http://api.flickr.com/services/feeds/photos_public.gne?tags=nature&tagmode;=any&format;=json&jsoncallback;=?",
function(data) {
$.each(data.items, function(i, item) {
$("").attr("src", item.media.m)
.attr("title", item.title)
.appendTo("div#targetImg");
if (i == 2) return false;
});
});
});
Метод jQuery $.post
Отправляем данные на сервер; ответ вставляем в определенный элемент.
jQuery or Javascript
$(".load").click(function() {
$.post("testPost.php", {
name: "Константин",
age: "33"
},
function(data) {
$("div#target").text(data);
});
});
PHP
header('Content-Type: text/html; charset=utf-8');
if($_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest') {
if($_POST) {
print 'Имя: ' . $_POST['name'] . ', возраст: ' . $_POST['age'] . ', время: ' . date('H:i:s', time());
}
}
Методы jQuery $.ajax() и $.ajaxSetup()
- Отправляем данные на сервер
- Выполняем действия перед отправкой на сервер
- Контролируем max время ожидания ответа
- В случае успеха выполняем какое-либо действие
jQuery or Javascript
$(".load").click(function() {
$.ajax("testAjax.php", {
type: "POST",
data: $('form').serialize(),
timeout: 5000,
beforeSend: function() {
$("#target").text("Загрузка...");
},
success: function(data, textStatus, jqXHR) {
$("#target").html(data + '<br />Статус ответа: ' + textStatus +
'<br />Код ответа сервера: ' + jqXHR.status);
},
error: function(jqXHR, textStatus) {
$("#target").html( textStatus +
'<br />Код ответа сервера: ' + jqXHR.status);
}
});
});
PHP
header('Content-Type: text/html; charset=utf-8');
if($_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest') {
for($i=0;$i<2;$i++){
sleep(1);
}
if($_POST){
print '<h3>Ответ сервера</h3><p>Время: '.date("H:i:s", time()).'</p>
<p>Имя: ' . $_POST['name'] . ', возраст: ' . $_POST['age'].'</p>';
}
}
Ajax-запросы идентичны, но различие в отправляемых данных
Настройки используемые в $.ajaxSetup()
будут использоваться для всех ajax-запросов страницы.
jQuery or Javascript
$(function() {
$.ajaxSetup({
url: "testAjaxSetup.php",
type: "POST",
timeout: 3000,
beforeSend: function() {
$("#target").empty();
$("#result").text("Загрузка...");
},
success: function(data) {
$("div:last").html(data);
$("#result").text("Готово!");
},
error: function(jqXHR, textStatus) {
$("#result").html('Статус ответа: ' + textStatus +
'<br />Код ответа сервера: ' + jqXHR.status);
}
});
$("button:eq(0)").click(function() {
$.ajax({
data: "q=1&er;=none"
});
});
$("button:eq(1)").click(function() {
$.ajax({
data: "q=3&er;=yes"
});
});
});
PHP
header('Content-Type: text/html; charset=utf-8');
if($_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest') {
if($_POST['er'] == "yes") { for($i=0;$i<5;$i++) sleep(1); }
if($_POST){
print '<h3>Ответ сервера</h3>
<p>В '.date("H:i:s d-m-Y", time()).
' получены данные:<br />
<strong>q = ' . $_POST['q'] . ',
er = ' . $_POST['er'] .
'</strong></p>';
}
}
Локальные и глобальные события при AJAX-запросе
new Date().getTime()
- время прошедшее с 1 января 1970 года, в мс.
jQuery or Javascript
$(function() {
var start = new Date().getTime();
// глобальные настройки
$.ajaxSetup({
url: "testEvents.php",
type: "POST",
timeout: 4000,
beforeSend: function() {
$("#result").append(new Date().getTime() - start + ' мс ==> beforeSend');
},
success: function() {
$("#result").append(new Date().getTime() - start + ' мс ==> success');
},
error: function() {
$("#result").append(new Date().getTime() - start + ' мс ==> error');
},
complete: function() {
$("#result").append(new Date().getTime() - start + ' мс ==> complete');
}
});
// успешный запрос
$("#well").click(function() {
$("div").empty();
start = new Date().getTime();
$.ajax({
data: "er=none"
});
});
// ошибочный запрос
$("#bad").click(function() {
$("div").empty();
start = new Date().getTime();
$.ajax({
data: "er=yes"
});
});
$("#clear").click(function() {
$("div").empty();
});
// обработка глобальных событий
$(document).ajaxStart(function() {
$("#result2").append(new Date().getTime() - start + ' мс ==> ajaxStart');
}).ajaxSend(function() {
$("#result2").append(new Date().getTime() - start + ' мс ==> ajaxSend');
}).ajaxSuccess(function() {
$("#result2").append(new Date().getTime() - start + ' мс ==> ajaxSuccess');
}).ajaxError(function() {
$("#result2").append(new Date().getTime() - start + ' мс ==> ajaxError');
}).ajaxComplete(function() {
$("#result2").append(new Date().getTime() - start + ' мс ==> ajaxComplete');
}).ajaxStop(function() {
$("#result2").append(new Date().getTime() - start + ' мс ==> ajaxStop');
});
});
PHP
header('Content-Type: text/html; charset=utf-8');
if($_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest') {
if($_POST['er'] == "yes") {
sleep(5);
}
}
Формируем запрос руками
GET и POST запросы
var params = 'name=' + encodeURIComponent(name) +
'&surname;=' + encodeURIComponent(surname);
Чтоб избежать неожиданных запросов к серверу, вам следует вызывать encodeURIComponent для любых вводимых пользователем параметров, используемых как часть URI.
developer.mozilla.org: encodeURIComponent
Кросс-доменные запросы
CORS
learn.javascript.ru: xhr-crossdomain#cors
В кросс-доменный запрос браузер автоматически добавляет заголовок Origin
, содержащий домен, с которого осуществлён запрос.
GET /request
Host:anywhere.com
Origin:http://blalala.com
...
Сервер должен, со своей стороны, ответить специальными заголовками, разрешает ли он такой запрос к себе.
Если сервер разрешает кросс-доменный запрос с этого домена – он должен добавить к ответу заголовок Access-Control-Allow-Origin
, содержащий домен запроса (в данном случае «blalala.com
») или звёздочку *
.
Вероятный ответ сервера:
HTTP/1.1 200 OK
Content-Type:text/html; charset=UTF-8
Access-Control-Allow-Origin: http://javascript.ru
Запросы от имени пользователя
По умолчанию браузер не передаёт с запросом куки и авторизующие заголовки.
var xhr = new XMLHttpRequest();
xhr.withCredentials = true;
Полезные статьи
Основы XMLHttpRequest https://learn.javascript.ru/ajax-xmlhttprequest
AJAX. Основы.easywebscripts.net/ajax/ajax_fundamentals.php
При запросе с withCredentials
сервер должен вернуть уже не один, а два заголовка:
Access-Control-Allow-Origin: домен
Access-Control-Allow-Credentials: true
p.s. Функция sleep
Откладывает исполнение программы на число секунд, заданное параметром seconds.
php.net/manual/ru/function.sleep.php
Комментарии к статье