2. easyAPI. Удаленная загрузка XML.

Вячеслав Гринин, January 30, 2010

И вот, наконец, долгожданная, вторая статья из раздела easyAPI.

Сегодня мы узнаем, как загрузить XML-данные с удаленного домена. Подобная задача возникает, например, когда владелец сайта на бесплатном (а значит – без серверного кода) хостинге хочет вставить в страницу погодный XML-информер. Именно на этом примере мы и рассмотрим сегодня удаленную загрузку XML-файлов.

Итак, для фоновой загрузки данных мы привыкли использовать так называемый AJAX, то есть объект XMLHttpRequest, про эту технологию я уже не раз писал в статьях блога. Однако, эта технология в данном случае никуда не годится. Почему? А потому что объект XMLHttpRequest не позволяет делать запросы к доменам, иным, чем тот, в котором работает скрипт, создающий этот объект.

И здесь к нам на помощь приходит технология, получившая название JSONP, что значит JavaScript Object Notation with Padding. Про сам JSON можео почитать вот здесь JSON, а JSONP представляет собой объект в нотации JSON обернутый в вызов функции, что-то вроде этого:

onSuccess('JSON-object')

А теперь объясню, зачем это нужно. Хоть XMLHttpRequest и не позволяет делать запросы к удаленным доменам, однако все браузеры позволяют нам загружать JavaScript’ы с любых доменов, то есть страница, загруженная с домена localdomain.ru, позволяет выполнить в ее рамках следующую инструкцию:

<script type='text/javascript' src='http://remotedomain.ru'>
</script>

А теперь смотрите, что происходит. Наша страница загружает скрипт с удаленного домена, а скрипт этот возвращает нам JSONP-конструкцию, которая после загрузки скрипта тут же и выполнится, а значит, вызовет некую предопределенную заранее функцию onSuccess, которая получит в качестве аргумента тот самый XML-файл. И теперь мы можем делать с ним все, что захотим!

Осталось только одно – завладеть таким remotedomain.ru, который вернет нам то, что нам нужно. Скажу, что домен этот – http://easyapi.ru. Да-да, именно на этом, предусмотрительно приобретенном не так давно домене, и будут жить все наши полезные, жизненно необходимые почти каждому веб-разработчику, функции. :) Скромненько и со вкусом…

Итак, в рамках домена easyapi.ru я уже создал ответную часть для удаленной загрузки XML-документов. Живет она вот здесь: http://easyapi.ru/xml/get.php и принимает на входе два GET-параметра: url и callback. Первый из них – адрес, с которого будет загружаться XML-файл, а второй – имя JavaScript-функции, которая будет вызвана после загрузки, и которая должна будет обработать полученный XML-документ.

Не откладывая дело в долгий ящик, приведу ниже содержимое страницы, которая, используя наш сервис easyAPI, загружает данные об XML-погоде в городе Москва и при помощи XSLT-шаблона преобразует эти данные в красивый информер, который вы, кстати, изучив основы XSLT-преобразований, сможете оформить по своему усмотрению.

Вот исходный код страницы:

<html>
<head>
<script type="text/javascript">
function getXMLFromString(s) {
    if(window.ActiveXObject)
    {
        var xml;
        xml=new ActiveXObject("Microsoft.XMLDOM");
        xml.async=false;
        xml.loadXML(s);
        return xml;
    }
    else if(window.DOMParser)
    {
      var parser = new DOMParser();
      return parser.parseFromString(s,'text/xml');
    }
    else
    {
        alert("Загрузка XML не поддерживается браузером");
        return null;
    }
}

function getXMLDocument(url)
{
    var xml;
    if(window.XMLHttpRequest)
    {
        xml=new window.XMLHttpRequest();
        xml.open("GET", url, false);
        xml.send("");
        return xml.responseXML;
    }
    else
        if(window.ActiveXObject)
        {
            xml=new ActiveXObject("Microsoft.XMLDOM");
            xml.async=false;
            xml.load(url);
            return xml;
        }
        else
        {
            alert("XML loading not supported");
            return null;
        }
}

function transformXslt(source,style) {
    if(window.ActiveXObject)
    {
        return source.transformNode(style);
    }
    else if(window.XSLTProcessor)
    {
        var xsltProcessor=new XSLTProcessor();
        xsltProcessor.importStylesheet(style);
        var resultDocument = xsltProcessor.transformToDocument(source);
        var xmls = new XMLSerializer();
        return xmls.serializeToString(resultDocument);
    }
    else
    {
        alert("Преобразование XML не поддерживается браузером");
        return null;
    }
}

</script>

</head>
<body>
<div id="res"></div>
<script type="text/javascript">
function onSuccess(res)
{
    var xslt = getXMLDocument("http://easy4web.ru/samples/easyxml/gis.xsl");
    var xml = getXMLFromString(res.result);
    var res = transformXslt(xml, xslt);
    document.getElementById("res").innerHTML=res;
}
</script>
<script src="http://easyapi.ru/xml/get.php?url=http://informer.gismeteo.ru/xml/27612_1.xml&callback=onSuccess" type="text/javascript"></script>
</body>
</html>

В первой части страницы мы видим три функции, все они – кроссбарузерные:

  • getXMLFromString(s) – преобразует валидную строку s в XML-документ
  • getXMLDocument(url) – загружает XML-документ с адреса url
  • transformXslt(source,style) – преобразует XML-документ source при помощи XSLT-шаблона style

В нижней части исходного кода мы видим функцию onSuccess – ока как раз и выполнится после загрузки xml-документа с удаленного домена. Она отрисует загруженный и полученный в переменной res.result XML-Документ при помощи XSLT-файла, хранящегося по адресу http://easy4web.ru/samples/easyxml/gis.xsl
И в самой-самой нижней части исходного кода мы видим вот такую конструкцию:

<script src="http://easyapi.ru/xml/get.php?url=http://informer.gismeteo.ru/xml/27612_1.xml&callback=onSuccess" type="text/javascript"></script> 

Вот эта часть и представляет собой загружалку XML-документов с удаленных доменов. Как видим в атрибуте src тега SCRIPT мы указали, кто будет заниматься загрузкой (http://easyapi.ru/xml/get.php), что он будет загружать (url=http://informer.gismeteo.ru/xml/27612_1.xml) и какая функция займется обработкой документа (callback=onSuccess)

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

В тему:

9комментариев

А файл get.php можете выложить?

Werot, March 18, 2010 2:13 am Reply

Нет, файл get.php, как и прочие исходные серверные файлы сервиса easyAPI я не выкладываю. Но если вкратце, то это просто загрузка файла, проверка mime-типа загружаемого файла, и в случае, если тип – XML, отдача файла пользователю.

admin, March 18, 2010 9:36 am Reply

В чем причина, http://easyapi.ru/xml/get.php не обрабатывает такой адрес http://www.morow.com/playlist.xml, вот пример:

function onSuccess()
{
alert(“Функция вызвана”)
}

Anton, October 18, 2010 1:53 am Reply

Исправил.

Обработчик ожидал, что ему придет Content-Type = text/xml, а от данного сайта приходил application/xml.

admin, October 18, 2010 8:59 am Reply

Спасибо, все получилось, правда, возникла проблема с кэшированием скрипта браузером, но это детали. Еще раз спасибо за эту статью и сервис :-)

Anton, October 18, 2010 9:43 pm Reply

Вот тоже хотел сделать себе на сайт. Модуль прогноза погоды.
Сайт стоит на CMS DLE 9.5
Шаблон написал сам, Javascript неделю назад начал читать и практиковать, раньше только на Java, C++, VB программировал.
Вроде как ваш код мне понятен, но я не могу понять почему у меня он не работает. Не из-за того что xslt обработчик находиться у вас на сервере? Хотя, если писать в функцию onSucces alert(“готово”), оно не выполняется. Может быть это из-за моего корявого JavaScript-а который был написан ранее, и я подключал библиотеку jQuery может это из-за него и как это можно вылечить?

Акуна, January 16, 2012 4:08 pm Reply

“Не из-за того что xslt обработчик находиться у вас на сервере?” – это я к тому что не должен ли он у меня на сервере лежать. Также я пробовал кучу способов с php. PHP в шаблоне игнорируется, подумал может в движке написать в файле index.php, написал, создал для него клише({moduleWeather}) сделал так чтобы он заменял клише на обработанную переменную типа string, обновил сайт, и тут ничего не происходило. Кажется я в отчаянии) а отказываться от этого я не собираюсь, хочу попробовать и опыт получить

Акуна, January 16, 2012 4:14 pm Reply

Разместите и скрипт и XSLT на своем сервере.

Вячеслав Гринин, January 16, 2012 10:35 pm Reply

Валюта Центробанка не парсится из-за русских букв http://easyapi.ru/xml/get.php?url=http://www.cbr.ru/scripts/XML_daily.asp&callback=onSuccess

Евгений, February 26, 2014 8:54 pm Reply
Ваше имя
Ваш email*
Ваш сайт
Текст вашего комментария:

Поиск по блогу:
Подписаться:
Популярные:
Облако тегов:
Разное:
Счетчик: