Меню
✘Скрыть меню
Меню заработка
✘Скрыть меню
Загрузка.. nostroma.online from NOSTROMA - best life and beautiful workЭто ужасно тяжелая работа — ничего не делать – Оскар УайльдРешающую роль в работе играет не всегда материал, но всегда мастер – Максим ГорькийЯ слишком энергичен, чтобы работать – Марсель АшарЧто привлекло меня в карьере писателя? Отсутствие бумажной работы.Одни люди работают только для того чтобы работать, другие – для того, чтобы иметь возможность не работать в будущем.Занятие ерундой на рабочем месте развивает боковое зрение, слух и бдительность в целомСтоит статýя в лучах заката с огромным буем, в руках - граната.Друзья, если вы попались на лохотрон, не будьте эгоистами - предупредите других о таком сайте!Секрет гения — это работа, настойчивость и здравый смысл. Томас Эдисон
Меню заработка

Курсы JavaScript

Урок 16. AJAX, объект XMLHttpRequest

Содержание курса

Обратность и асинхронность

Для начала рассмотрим, чем отличается обратность от асинхронности: обратность - это когда действия происходят одно за другим, например, если вы используете метод map и подаёте ему на вход безымянную функцию обратного вызова. То же самое происходит при переборе списка.

В случае асинхронности действия выполняются не одно за другим, а по мере готовности, параллельно.

Обратность

В следующем примере ещё раз наглядно приведён пример обратности - использовано несколько методов (find, map, get, reduce) и каждый последующий из них использует результат, возвращённый предыдущим:

<!DOCTYPE html>
	<html>
		<head>
			<meta charset="utf-8">
			<title>Обратность</title>
			<script src="/library/jquery-3.0.0.min.js"></script>
		</head>
		<body>
		
		<button>Сумма</button>
		
		<ul>
			<li><input value="11"></li>
			<li><input value="22"></li>
			<li><input value="33"></li>
			<li><input value="44"></li>
			<li><input value="55"></li>
		</ul>
		
		<script>
			$('button').on('click', function(){
				var sum = $('ul').find('input')
					.map(function(){
						return +$(this).val();
					})
					.get()
					.reduce(function(a, b){
						return +a + +b;
					});
				$(this).text(sum);
			});
		</script>
		
		</body>
	</html>
Показать в браузере (откроется в новой вкладке)

В результате при нажатии на кнопку "сумма" мы запускаем цепочку всех этих методов и получаем сумму значений полей ввода в виде надписи на кнопке.

Пример обратности также ярко демонстрирует код примера в уроке 14, когда перебирается список из объектов, где каждый объект кроме последнего содержит внутри себя ссылку на следующий.

Асинхронность. AJAX

Асинхронность проявляется в том, что интерфейс реагирует на действия пользователя параллельно с обработкой ответов от сервера.

AJAX - Asynchronous JavaScript And XML - подход к клиентской разработке, суть которого в том, что при отправке запросов от клиента серверу данные в ответ приходят "порциями" и при этом вся текущая страница не перезагружается. Сегодня это фактический стандарт пользовательского интерфейса.

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

В настоящее время наиболее распространена нотация JSON, а не XML, поэтому правильнее было бы говорить AJAJ - Asynchronous JavaScript And JSON, а не AJAX.

При асинхронном AJAX запросе от сервера приходит заголовок

header('Content-Type: application/json'),

что говорит клиентской стороне о том, что полученные данные нужно интерпретировать как JSON:

var obj = {'name':'Aleksandr', 'age':'33'};
obj;
/* Выведет: Object {name:'Aleksandr', age:'33'} */

JSON.stringify(obj);
/* Выведет: "Object {"name":"Aleksandr", "age":"33"}" */

О методе передачи данных GET

Каждый раз, когда вы нажимаете на гиперссылку или вводите адрес в адресную строку браузера, он отправляет запрос методом GET, при этом детали запроса видны прямо в адресной строке.

В адресах типа http://nostroma.online/courses/?cru=16 то, что находится после вопросительного знака называется Query String. Обратите внимание, что Query String состоит из пар (одной или нескольких) ключ=значение, если таких пар несколько, то они разделяются амперсандами (&):
http://nostroma.online/courses/?cru=16&vsr=5

Объект XMLHttpRequest

Для того, чтобы програмно отправлять асинхронные запросы и обрабатывать поступающие ответы, нужно использовать специальный объект - XMLHttpRequest:

var x = new XMLHttpRequest();

Смоделируем ситуацию асинхронного запроса

Для моделирования асинхронности используем таймер - наиболее простой и наглядный способ:

<!DOCTYPE html>
	<html>
		<head>
			<meta charset="utf-8">
			<title>асинхронные запросы</title>
		</head>
		<body>
		
		<h1>CallBack - смотри консоль</h1>
		<button id="b1">неудача</button>
		<button id="b2">успешно</button>
		
		<script>
			console.clear()
			
			/* здесь объявляется первая функция, которая терпит неудачу */
			function Outer1(){
				var result;
				setTimeout(function(){
					result = 545;
					console.log(result);
				}, 3000);
				return result;
			}
			
			document.querySelector('#b1').addEventListener('click', function(){
				/* вызов первой функции */
				console.log( Outer1() );
			});
			
			/* здесь объявляется вторая функция, которая выполняется успешно */
			function Outer2(whatDo) {
				var result;
				setTimeout(function(){
					result = 545;
					whatDo(result);
				}, 3000);
			}
			
			document.querySelector('#b2').addEventListener('click', function(){
				/* вызов второй функции */
				Outer2( function(x) {console.log(x)} );
			});
		</script>
		
		</body>
	</html>

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

Функция обратного вызова, указанная внутри таймера доступна только внутри Outer1(), если требуется получить к ней доступ, то используется функция Outer2(), которая принимает аргумент do, она описана в коде примера.


Демонстрация XMLHttpRequest

В следующем примере рассмотрим рабочий код программной отправки запросов и обработки ответов с использованием объекта XMLHttpRequest:

<!DOCTYPE html>
	<html>
		<head>
			<meta charset="utf-8">
			<title>Демонстрация XMLHttpRequest</title>
		</head>
		<body>
		
		<h1>Нажать сюда!</h1>
		
		<script>
			console.clear();
			/* Объявляем объект для AJAX */
			var xhr = new XMLHttpRequest();
			
			/* Объявляем функцию */
			function Outer3(o, whatDo){
				xhr.open('GET', 'http://nostroma.online/examples/date.php', true);
				xhr.onload = function(e){
					if(this.status == 200){
						whatDo(o, JSON.parse(this.responseText));
					};
				};
				xhr.send();
			};
			
			/* Вызываем объявленную функцию */
			document.querySelector('h1').addEventListener('click', function(e){
				this.style.color = 'red';
			
			/* Передаём CallBack в эту функцию, которая сама зависит от CallBack */
			Outer3(this, function(o, x){
					o.textContent = x.date1 + '->' + x.date2;
					o.style.color = 'black';
				});
			});

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

Следующий код асинхронного запроса посылает запрос на сервер каждую секунду и отображает часы сервера в реальном времени:

<!DOCTYPE html>
	<html>
		<head>
			<meta charset="utf-8">
			<title>Демонстрация XMLHttpRequest - время сервера</title>
		</head>
		<body>
		
		<script>
		
			/* Запрос данных */
			function showServerTime(){
				var xhr = new XMLHttpRequest();
				xhr.onreadystatechange = function(){
					if(xhr.readyState != 4) {return;};
					var spanTime = document.querySelector('#spanTime');
					spanTime.textContent = xhr.responseText;
				};
				xhr.open("GET", "http://nostroma.online/examples/server_time.php", true);
				xhr.send(null);
			};
			
			/* Автозапуск */
			window.onload = function(){
				setInterval("showServerTime()", 1000);
			};
			
		</script>
		
		<p>Сейчас на сервере:</p>
		
		<p id="spanTime"></p>
		
		</body>
	</html>
Показать в браузере (откроется в новой вкладке)

Асинхронная передача данных на сервер

Если с помощью AJAX можно асинхронно получать данные с сервера, то, как вы уже догадались, их можно также и асинхронно передавать. Это реализуется следующим JavaScript кодом:

var x = document.querySelector('#a').value;
xhttp=new XMLHttpRequest();
xhttp.onreadystatechange=function(){
   if (xhttp.readyState==4 && xhttp.status==200)
      document.querySelector('#ajax').innerHTML = xhttp.responseText;
   };
xhttp.open('POST','addpost.php',true);
xhttp.setRequestHeader('Content-type','application/x-www-form-urlencoded');
xhttp.send(x);

Важное замечание: чтобы передать данные на сервер в том же формате, что и HTML-формы, нужно указать соответствующий заголовок - xhttp.setRequestHeader('Content-type','application/x-www-form-urlencoded');

Комментарии

Введите Ваше имя:*

Введите e-mail:

Ваш комментарий:*

* Обязательные поля