Динамическое получение данных (AJAX)

Материал из ISPWiki

Перейти к: навигация, поиск

Не многие знают, что с октября 2010 года все наши продукты имеют возможность вывода информации в формате JSON (json.org), в добавок к уже имеющимся text, xml и devel.

Покажем, как можно получить данные от любой панели *manager по API с помощью JavaScript, динамически.

Теория

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

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

И третий способ - с помощью создания объекта <script>, используя его свойство получать данные независимо от сервера назначения. Однако, получаемые данные должны быть валидным JavaScript'ом. И именно тут приходит на помощь JSON! Т.к. данный формат является ни чем иным, как описанием объекта JavaScript.

Для примера, сделаем такой API запрос к сферическому ISPmanager'у (как вы понимаете, запрос можно делать к любой панели):

https://IP/manager/ispmgr?func=user&out=json

Разумеется, чтобы получить ответ, необходимо сначала авторизоваться в ISPmanager'е. Любым из способов, перечисленных в статье Примеры работы с API, в разделе "Методы авторизации".
Посмотрим, что возвращает данный запрос:

{
"elem": [
	{
		"name": "user1",
		"disk": {
			"used": 0,
			"limit": 1000
		},
		"bandwidth": {
			"used": 0,
			"limit": 100000
		},
		"ssi": "on",
		"cgi": "on",
		"php": "on",
		"preset": "Example package"
	},
	{
		"name": "user2",
		"disk": {
			"used": 0,
			"limit": 1000
		},
		"bandwidth": {
			"used": 0,
			"limit": 100000
		},
		"ssi": "on",
		"cgi": "on",
		"php": "on",
		"preset": "Example package"
	}
]
}

Однако сами по себе JSON данные никакой пользы не дадут в скрипте, надо их как-то обработать. Для этого, при запросе данных в этом формате, вы можете указать необязательный параметр callback:

https://IP/manager/ispmgr?func=user&out=json&callback=myfunc

При этом в начале вывода и в конце строчки изменятся следующим образом:

myfunc({
--8<--
});

Это ни что иное, как вызов функции с именем myfunc, параметром к которой передается объект в формате JSON. Данную функцию вы должны определить заранее - таким образом вы можете получить данные от любой панели с помощью JavaScript динамически, и встроить вывод, например, на ваш сайт, или в Вашу админку.

Практика

Для получения данных необходимо будет создать объект <script> и загрузить в него ответ от *manager:

// создание элемента script и загрузка данных в json формате
function getJSONdata(url) {
  var headID = document.getElementsByTagName("head")[0];
  var newScript = document.createElement('script');
  newScript.type = 'text/javascript';
  newScript.src = url;
  headID.appendChild(newScript);
}

Теперь создадим функцию обработки данных:

// вывод результата запроса
function myJSONcallback(obj) {
  var elem = obj.elem
  var reshtml = '<table>';
  for ( var i = 0; i < elem.length; i++) {
    reshtml += '<tr><td>'+elem[i].name+'</td>\
        <td>'
+elem[i].ssi+'</td>\
        <td>'
+elem[i].cgi+'</td>\
        <td>'
+elem[i].php+'</td>\
        <td>'
+elem[i].preset+'</td></tr>';
  }
  reshtml += '</table>';
  var reselement = document.getElementById("JSONresult");
  reselement.innerHTML = reshtml;
}

Вывод в таблице disk и bandwidth будет домашним заданием ;)
Конечно, реализация может отличаться (например добавлять данные на страницу можно с помощью создания таблицы createElement и добавления строк insertRow/insertCell), мы показываем суть.

Как видите, функция myJSONcallback пишет данные в элемент с id=JSONresult, он должен быть на странице (или создан динамически заранее):

<div class="JSONresult" id="JSONresult"></div>

Осталось самая малось - запустить наш динамический запрос, например при клике по ссылке (или кнопочке):

// вызов функции getJSONdata
function clickAJAX() {
  var reselement = document.getElementById("JSONresult");
  reselement.innerHTML = "loading...";
  var url = "https://IP/manager/ispmgr?authinfo=root:rootpassword&func=user&out=json&callback=myJSONcallback";
  getJSONdata(url);
  return false;
}

--8<--

<a href="#" onclick="return clickAJAX();">Нажмите для загрузки данных</a>

Вот и все! Теперь при клике на ссылку в указанном элементе <div> с id=JSONresult будет показана таблица с данными из ISPmanager.

Неявные моменты

В написанном примере авторизация в ISPmanager прописана прямо в скрипте, в виде authinfo=root:rootpassword в ссылке. В реальных условиях, в большинстве случаев, так делать разумеется не стоит, т.к. JavaScript передается клиенту открытым текстом и не составляет сложности вычленить пароль root (или каким производится авторизация) из него. Как хранить пароль? На этот вопрос нельзя ответить однозначно, все зависит от ваших задач. Например, можно сделать вход на сайт по данным авторизации ISPmanager, и сохранять логин/пароль в cookies.

Второй момент. Если ISPmanager по какой-то причине не отвечает - клиент будет вечно смотреть на надпись loading. Хорошо бы сказать ему об ошибке. Как? Т.к. контролировать загрузку файла таким образом нельзя, можно создать таймер. Если по истечению например 10-20 секунд данные не были загружены - показывать ошибку. Если ответ пришел и функция callback запустилась - внутри неё таймер надо будет остановить.

Была ли эта информация полезной? Да | Нет
Личные инструменты