[Disclaimer: Данная статья была переведена в рамках "Конкурса на лучший перевод статьи" на сервисе Quizful. Ссылка на оригинал находится внизу страницы.]
Со времени моего последнего AJAX – проекта я все чаще задавался вопросом об идеальной форме ответа AJAX – приложения.
Итак, у вас удачно прошел AJAX-запрос, какой же ответ должен прийти от сервера? В виде XML документа? Фрагмент HTML? Может, в формате JSON, строка которого преобразуется в JavaScript код? Или есть четвертый вариант? В этот раз я хотел бы обсудить три формата, привести примеры каждого, и спросить у вас, читателей, какой формат Вы применяли на практике в своих AJAX-приложениях.
Когда Вы получаете дополнительные данные для вашего AJAX – приложения, вам следует запустить скрипт, который разместит эти экстра-данные на вашу HTML – страничку. Определенно, вид скрипта в большей степени зависит от формата полученных вами данных. Есть ли необходимость искать XML – документ для специальных узлов и копировать их код в HTML? Или Вы предпочли бы получить фрагмент HTML кода, который нужно добавить на страничку в таком виде, "как он есть"?
В моем последнем проекте я получил часть данных в формате XML и часть данных в HTML. Чтобы поместить данные на страницу, для этих форматов требуются разные типы скриптов. В обоих случаях, как для форматов данных, так и скриптов под них, есть преимущества и недостатки.
После того, как я закончил работу над своим последним проектом, я углубился в изучение JavaScriptObjectNotation (JSON). Формат обмена данными JSON был разработан программистом Дугласом Крокфордом и в недавнем времени был принят форматом вывода по умолчанию для большинства сервисов Yahoo. Да, и, кажется, мне это нравится, хотя я еще никогда этим не пользовался.
И все же, какой формат лучше? Какой формат вы находите наилучшим, или, по крайней мере, наиболее применимым на практике в AJAX среде?
Примеры
Для примера всех трех форматов возьмем книжный online-магазин под управлением AJAX. Сделаем запрос на книги по JavaScript, имеющиеся в магазине, и по случайному совпадению в наличии как раз эти три книги по JavaScript, лежащие на моем столе. AJAX- запрос возвращает эти три результата, теперь нужно включить их в HTML-страницу. Далее я приведу примеры всех трех форматов и простых скриптов, которые разместят результаты в слое с идентификатором «writeroot»: <div id="writeroot">".
XML документы
XML документ является первым и наиболее очевидным выбором формата вывода. Исходная идея, лежащая в основе XMLHTTP-объектов, заключалась в импортировании документов XML, поэтому не удивительно, что большее внимание получил формат XML и до сих пор считается форматом по умолчанию.
Пример
Сервер вернул XML документ:
<books>
<book>
<title>JavaScript, the Definitive Guide</title>
<publisher>O'Reilly</publisher>
<author>David Flanagan</author>
<cover src="/images/cover_defguide.jpg" />
<blurb>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</blurb>
</book>
<book>
<title>DOM Scripting</title>
<publisher>Friends of Ed</publisher>
<author>Jeremy Keith</author>
<cover src="/images/cover_domscripting.jpg" />
<blurb>Praesent et diam a ligula facilisis venenatis.</blurb>
</book>
<book>
<title>DHTML Utopia: Modern Web Design using JavaScript & DOM</title>
<publisher>Sitepoint</publisher>
<author>Stuart Langridge</author>
<cover src="/images/cover_utopia.jpg" />
<blurb>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</blurb>
</book>
</books>
Нам нужно, чтобы этот скрипт отобразил результаты в нашем слое <div>.
function setDataXML(req) {
var books = req.responseXML.getElementsByTagName('book');
for (var i=0;i<books.length;i++) {
var x = document.createElement('div');
x.className = 'book';
var y = document.createElement('h3');
y.appendChild(document.createTextNode(getNodeValue(books[i],'title')));
x.appendChild(y);
var z = document.createElement('p');
z.className = 'moreInfo';
z.appendChild(document.createTextNode('By ' + getNodeValue(books[i],'author') + ', '
+ getNodeValue(books[i],'publisher')));
x.appendChild(z);
var a = document.createElement('img');
a.src = books[i].getElementsByTagName('cover')[0].getAttribute('src');
x.appendChild(a);
var b = document.createElement('p');
b.appendChild(document.createTextNode(getNodeValue(books[i],'blurb')));
x.appendChild(b);
document.getElementById('writeroot').appendChild(x);
}
}
function getNodeValue(obj,tag) {
return obj.getElementsByTagName(tag)[0].firstChild.nodeValue;
}
Гораздо больше строк кода, как вы видите. Хотя W3C DOM дает нам полный доступ и к XML- документу, приходящему от сервера, и к HTML- документу, где и должны быть отражены данные, но он не дает изящного и простого пути извлечения именно тех данных, которые нам нужны. Поэтому мы должны неоднократно углубляться в XML-документ.
Здесь бы удачно подошел XSLT, так как этот язык специально предназначен для преобразования XML- документов в другой вид XML, и так как XHTML – это и есть XML, мы также можем использовать его для создания фрагментов Интернет - страницы. Я не касался XSL(T) с 1999, тем не менее, несомненно существует много мелких проблем со совместимостью, которые я должен буду решить прежде, чем получить осуществимую демонстрационную версию. Так что, придержим XSLT до следующего раза.
Преимущества
Наиболее важным достоинством языка XML является его легкочитаемость «посторонними людьми».
Другой плюс заключается в том, что язык XML уже давно применяется, и много разработчиков успело привыкнуть к нему. Скажем, фраза: «Я бы хотел, чтобы скрипт с серверной стороны вернулся в формате XML» удивления не вызовет, в отличии от просьбы вернуть в виде JSON-объекта.
Недостатки
Для
вставки данных в HTML
страницу требуется довольно многострочный
JavaScript. Я написал маленькую
удобную функцию getNodeValue(),
чтобы освободиться от наиболее громоздкой и
скучной части кода, а именно, считывания
строк в тэге XML.
Тем не менее, скрипт никогда не станет
образцовым.
HTML фрагменты
Второй и, возможно, наиболее интересный формат вывода – это кусок HTML. Заметьте, что я называю именно «кусок» HTML, потому как мы не получаем целую страницу HTML. Вместо нее нам приходит тот кусочек HTML кода, который должен быть помещен в наш слой <div>.
Пример
Сервер возвращает такой HTML фрагмент:
<div class="book">
<h3>JavaScript, the Definitive Guide</h3>
<p class="moreInfo">By David Flanagan, O'Reilly</p>
<img src="/images/cover_defguide.jpg" />
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</p>
</div>
<div class="book">
<h3>DOM Scripting</h3>
<p class="moreInfo">By Jeremy Keith, Friends of Ed</p>
<img src="/images/cover_domscripting.jpg" />
<p>Praesent et diam a ligula facilisis venenatis.</p>
</div>
<div class="book">
<h3>HTML Utopia: Modern Web Design using JavaScript & DOM</h3>
<p class="moreInfo">By Stuart Langridge, Sitepoint</p>
<img src="/images/cover_utopia.jpg" />
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</p>
</div>
Скрипт очень прост: требуется только вставить полученный текст в нужный объект HTML страницы, и все готово!
function setDataHTML(req) {
document.getElementById('writeroot').innerHTML = req.responseText;
}
Преимущества
Простота скрипта и является самым большим преимуществом данного метода.
Также, такой формат дает интересные варианты доступа. Можно было бы умными и сложными словами описать серверную часть скрипта для построения сформированной доступной HTML-страницы, которая могла быть показано на любом устройстве. Когда пришел ответ на AJAX-запрос, скрипт серверной части отбрасывает весь HTML код за исключением результатов поиска, или AJAX-скрипт сам осуществляет поиск результатов.
Конечно, возможно написать подобные полезные функции доступа, когда вы работаете с XML или JSON, но все же HTML формат остается наиболее простым решением.
Недостатки
В случае, когда HTML кусок содержит формы, или получаемый HTML-элемент и есть форма, то такой метод вызывает ужаснейшие ошибки в Explorer.
При этом HTML фрагменты могут стать весьма и весьма сложными. К примеру, приведенному выше, это не относится, но как только вы захотите применить продвинутые возможности CSS, это потребует большего количества элементов, чем необходимо, фрагмент кода должен будет содержать дополнительные тэги <span> или другие нужные вам элементы. Таким образом, скрипт серверной части, который генерит HTML, может стать довольно громоздким.
JSON
Третий рассматриваемый нами метод – это JavaScript Object Notation (JSON). Лично я произношу это как "Ясон", так что еще один греческий герой сотворил современную JavaScript. (И, пожалуйста, помните, что отец Аякса Теламон сопровождал Ясона в качестве аргонавта. Ясон был старше и, в целом, более успешен, чем Аякс).
Главная идея заключается в получении куска текста (строки, по существу), которая может быть интерпретируема как код JavaScript. Как только пришел текст, вы используете методeval для перевода строки в реальный JavaScript код, который затем считываете.
Пример
Сервер возвращает следующий JSON-код:
{"books":[{"book":
{
"title":"JavaScript, the Definitive Guide",
"publisher":"O'Reilly",
"author":"David Flanagan",
"cover":"/images/cover_defguide.jpg",
"blurb":"Lorem ipsum dolor sit amet, consectetuer adipiscing elit."
}
},
{"book":
{
"title":"DOM Scripting",
"publisher":"Friends of Ed",
"author":"Jeremy Keith",
"cover":"/images/cover_domscripting.jpg",
"blurb":"Praesent et diam a ligula facilisis venenatis."
}
},
{"book":
{
"title":"DHTML Utopia: Modern Web Design using JavaScript & DOM",
"publisher":"Sitepoint",
"author":"Stuart Langridge",
"cover":"/images/cover_utopia.jpg",
"blurb":"Lorem ipsum dolor sit amet, consectetuer adipiscing elit."
}
}
]}
Данный кусок кода очень похож на XML скрипт. Выполняет те же функции, код просто считывает данные другого формата. Здесь также мог подойти XSLT.
function setDataJSON(req) {
var data = eval('(' + req.responseText + ')');
for (var i=0;i<data.books.length;i++) {
var x = document.createElement('div');
x.className = 'book';
var y = document.createElement('h3');
y.appendChild(document.createTextNode(data.books[i].book.title));
x.appendChild(y);
var z = document.createElement('p');
z.className = 'moreInfo';
z.appendChild(document.createTextNode('By ' + data.books[i].book.author + ', '
+ data.books[i].book.publisher));
x.appendChild(z);
var a = document.createElement('img');
a.src = data.books[i].book.cover;
x.appendChild(a);
var b = document.createElement('p');
b.appendChild(document.createTextNode(data.books[i].book.blurb));
x.appendChild(b);
document.getElementById('writeroot').appendChild(x);
}
}
Преимущества
Самым главным достоинством данного формата является то, что JSON обходит политику того же JavaScript, если вы импортируете JSON-файл как новый <script> тэг. Подробности можно найти в примере Саймона Вилисона.
JavaScript не дает доступа к документам (будь они в формате XML или HTML), приходящим с другого сервера. Однако, при импортировании JSON-файла скрипт-тэгом, вы избегаете этой проблемы, и любые JSON-данные могут быть переданы на любой веб-сайт. Это зависит от вашей цели, хорошо это или плохо, но на данный момент это единственный формат данных, представляющий неограниченный доступ.
Второе преимущество заключается в том, что скрипты для JSON-данных более простые и приближенные к остальному языку JavaScript, по сравнению со скриптом для XML данных.
Недостатки
Самый главный недостаток JSON кроется в том, что он очень труден для понимания людьми, и в том, что каждая отдельная запятая, кавычка, и скобка должны быть в определенном правильном месте. В то время как это также верно для XML, путаницы в языке JSON из-за сложно читаемого синтаксиса, как}}]} в конце куска данных, может напугать новичков и усложнить отладку.
Ваш выбор?
Итак, мы рассмотрели три формата вывода, которые можно использовать для получения AJAX данных. Я был бы рад сказать, какой из них наилучший. Мне кажется выбор подходящего формата зависит от конкретных условий, а не только от каких-то теоретических размышлений.
Тем не менее, давайте попробуем найти наилучший формат. Я задам вам несколько вопросов:
- Можете ли вы предложить иной формат вывода?
- Какой формат вывода вы применяли на практике в коммерческих AJAX-приложениях? (Демо-версии и что-то в этом роде не считаются)
- Будете ли вы переходить на другой формат в будущем? Если да, то на какой и почему?
Можете ли вы назвать еще достоинства и недостатки представленных трех форматов?
Отвечаю на собственные вопросы:
- Нет, иного формата данных предложить не могу.
- Применял в основном XML документы, немного HTML фрагментов.
- Собираюсь тщательно изучить JSON и, возможно, перейду на него из-за неограниченного доступа к задуманному приложению. Тем не менее, мне кажется, что XML продолжает оставаться лучшим форматом хотя бы потому что люди им пользуются.
- Я уже написал все преимущества и недостатки, которые мог придумать.
----------
Оригинальный текст статьи: The AJAX response: XML, HTML, or JSON?