Сейчас мы с вам начнем изучать работу с методом fetch. Для этого вам необходим браузер и какой-нибудь web сервер: это может быть PHP, либо NodeJS, либо что-то другое - не имеет значения.
В нашем случае важно, чтобы при обращении на определенные URL ваш сервер отдавал в браузер HTML страницы.
Для начала нам нужны две страницы: страница client, части которой мы будем обновлять через AJAX, и страница ajax, содержимое которой мы будем получать через AJAX.
Пусть страница client будет доступна по адресу /client/, а страница ajax - по адресу /ajax/.
Пусть на странице client будет расположен div и кнопка:
<!DOCTYPE html>
<html>
<head>
<title>Тайтл страницы</title>
</head>
<body>
<div id="result"></div>
<input type="submit" id="button">
</body>
</html>
А на странице ajax - три абзаца:
<p>1</p>
<p>2</p>
<p>3</p>
Обратите внимание на то, что страница client содержит всю необходимую структуру HTML, а страница ajax - нет.
Все дело в том, что страница client будет загружена в браузер и видима пользователю, а страница ajax будет подгружаться как кусочек HTML кода в какое-то место другой страницы, поэтому теги html, head, body здесь будут лишними.
В дальнейшем я для краткости буду опускать всю структуру страницы client, но эта структура должна быть, имейте ввиду.
Выполняем AJAX запросы
Итак, на странице client у нас есть кнопка и div. Давайте сделаем так, чтобы по нажатию на кнопку через AJAX загрузилось содержимое страницы ajax и отобразилось в теге нашем div.
Начнем с навешивания события на кнопку:
<div id="result"></div>
<input type="submit" id="button">
let result = document.getElementById('result');
let button = document.getElementById('button');
button.addEventListener('click', function() {
// выполним AJAX запрос
});
Для выполнения AJAX запроса используется функция fetch. У нее есть только один обязательный параметр - адрес страницы, содержимое которой мы хотим получить.
Например, для получения страницы по адресу /ajax/ необходимо написать вот так: fetch('/ajax/'). Вот полный код:
<div id="result"></div>
<input type="submit" id="button">
let result = document.getElementById('result');
let button = document.getElementById('button');
button.addEventListener('click', function() {
fetch('/ajax/'); // выполняем AJAX запрос
});
Итак, в нашем коде fetch('/ajax/') получает содержимое страницы /ajax/. Логично, что своим результатом функция fetch должна вернуть текст запрошенной страницы.
На самом деле это не совсем так. Дело в том, что после вызова fetch проходит некоторое время, прежде, чем будет получен ответ сервера. При этом JavaScript код, который расположен ниже функции fetch продолжит выполняться.
То есть мы имеем дело с асинхронным кодом. Это значит, что после вызова fetch весь остальной JavaScript код продолжит свое выполнение, а результат вызова fetch будет доступен только после загрузки запрошенной страницы.
Поэтому fetch возвращает не текст запрошенной страницы, а промис:
<div id="result"></div>
<input type="submit" id="button">
let result = document.getElementById('result');
let button = document.getElementById('button');
button.addEventListener('click', function() {
let promise = fetch('/ajax/'); // результатом будет промис
});
Чтобы получить данные из промиса, мы должны вызвать метод then, передав ему параметром анонимную функцию:
let result = document.getElementById('result');
let button = document.getElementById('button');
button.addEventListener('click', function() {
let promise = fetch('/ajax/');
promise.then(
function() {
}
);
});
При этом ответ сервера автоматически попадет в первый параметр нашей функции. Давайте назовем этот параметр response:
let result = document.getElementById('result');
let button = document.getElementById('button');
button.addEventListener('click', function() {
let promise = fetch('/ajax/');
promise.then(
function(response) {
// Ответ сервера лежит в переменной response
}
);
});
Переделаем наш код на более "взрослый" - вместо обычной функции для краткости напишем стрелочную:
let result = document.getElementById('result');
let button = document.getElementById('button');
button.addEventListener('click', function() {
let promise = fetch('/ajax/');
promise.then(
response => {
}
);
});
Итак, как я уже говорил, наша переменная response содержит ответ сервера. На самом деле в нашей переменной содержится достаточно сложный объект класса Response:
let result = document.getElementById('result');
let button = document.getElementById('button');
button.addEventListener('click', function() {
let promise = fetch('/ajax/');
promise.then(
response => {
console.log(response); // объект класса Response
}
);
});
Глубоко этот объект мы будем изучать в следующих уроках, а пока нам нужно самое простое - получить текст запрошенной страницы. Для этого в объекте response существует метод text.
То есть текст страницы можно получить так: response.text(). Однако, на самом деле это будет еще не текст, как кажется с первого взгляда, а снова промис:
let result = document.getElementById('result');
let button = document.getElementById('button');
button.addEventListener('click', function() {
let promise = fetch('/ajax/');
promise.then(
response => {
console.log(response.text()); // выведет Promise
}
);
});
Чтобы добраться до текста страницы, необходимо промис, полученный из response.text(), обработать еще раз:
let result = document.getElementById('result');
let button = document.getElementById('button');
button.addEventListener('click', function() {
let promise = fetch('/ajax/');
promise.then(
response => {
return response.text();
}
).then(
text => {
// В переменную text попадет текст страницы
}
);
});
Итак, мы наконец получили текст запрошенной страницы и можем, например, записать его в наш див:
let result = document.getElementById('result');
let button = document.getElementById('button');
button.addEventListener('click', function() {
let promise = fetch('/ajax/');
promise.then(
response => {
return response.text();
}
).then(
text => {
result.innerHTML = text;
}
);
});
Давайте соберем весь наш код вместе:
<div id="result"></div>
<input type="submit" id="button">
let result = document.getElementById('result');
let button = document.getElementById('button');
button.addEventListener('click', function() {
let promise = fetch('/ajax/');
promise.then(
response => {
return response.text();
}
).then(
text => {
result.innerHTML = text;
}
);
});
Если запустить приведенный код и нажать на кнопку, что через некоторое время (на локальном компьютере оно очень маленькое) в див загрузится содержимое страницы /ajax/.
Дан абзац и кнопка. Сделайте так, чтобы по нажатию на кнопку в абзац загружалось с сервера содержимое страницы по адресу /ajax/.
Даны 5 кнопок и абзац. Даны также страницы /1/, /2/, /3/, /4/ и /5/.
Сделайте так, чтобы каждая из кнопок подгружала в абзац соответствующую страницу.
Дана одна кнопка и страницы /1/, /2/, /3/, /4/ и /5/.
Пусть первое нажатие на кнопку подгружает первую страницу, второе нажатие - вторую, и так далее, пока страницы не закончатся.
Дана кнопка, абзац и страница /ajax/, которая возвращает текущее время. Сделайте так, чтобы по нажатию на кнопку в абзац загружалось с сервера содержимое страницы по адресу /ajax/.
Дана кнопка, список ul и страница /ajax/, которая возвращает текущее время. Сделайте так, чтобы по нажатию на кнопку с сервера загружалось содержимое страницы /ajax/ и добавлялось в новый тег li тега ul.
Модифицируйте предыдущую задачу так, чтобы вместо кнопки работал таймер, который каждые 2 секунды будет опрашивать страницу /ajax/ и добавлять результат в новый тег li тега ul.