Ajax начинает потихоньку матереть как технология, и в нем уже оформляются различные паттерны, подходы, школы (а с ними появляются и обязательные священные войны). В частности у нескольких людей уже (вот например заметка Фрэнка Соммерса, которая меня и сподвигла к написанию этой) я читал о том, что оформились два принципиально разных подхода к написанию ajax-приложений:
* создание готового HTML на сервере с автоматическим внедрением его в нужное место страницы * передача на страницу только структурированных данных и изменение по ним HTML’а скриптом на клиенте
Несмотря на то, что Фрэнк пишет, что эти два подхода несовместимы, я обнаружил, что сам как раз их смешиваю, причем мне кажется что удачно :-).
Подробнее о подходах Передача HTML
Подхода с передачей HTML’а идеально подходит для страниц, которые при взаимодействии с сервером меняются незначительно. Например некая форма, которая после сабмита на сервер опять появляется на экране, а вместе с ней либо рисуется картинка что все хорошо, либо рисуется список ошибок. В этом случае ajax позволяет сократить количество данных, передаваемых по сети, принимая с сервера не всю форму с индикацией, а только саму индикацию.
К несомненным плюсам этого подхода относится исключительная простота идеи, из которой прямо вытекает, что на клиентской стороне можно автоматизировать практически все:
* подмена сабмита формы javascript’овым обработчиком * формирование этим скриптовым обработчиком данных формы в вид, пригодный для сабмита на сервер (name1=value1&name2=value2) * получение ответа и внедрение его в страницу
Фактически все, что остается сделать программисту это:
* ткнуть пальцем в то, по какой кнопке он хочет "сделать ajax", и в какой блок на странице потом записать результат * на сервере объяснить фреймворку, какую именно часть ответа надо вырезать для ajax’ных запросов
К минусам подхода я бы отнес то, что он существенно хуже работает для "высокодинамических" страниц, где от одного действия меняются разные части. Например длинный тред комментариев, где по сабмиту формы с текстом с сервера должен прийти новый комментарий и, скажем, обновиться строчка "N комментариев", которая находится в совсем другом месте страницы. Здесь, если следовать автоматической модели, надо передавать на страницу ту ее часть, которая включает все нужные куски, даже если между ними есть данные, которые и не предполагались меняться. На практике это может привести к тому, что по сети гоняются немаленькие объемы данных, сравнимые с размером собственно страницы, и весь смысл ajax’а вырождается в отсутствие эффекта анимации иконки браузера в правом верхнем углу.
Причем мое подчеркнутое "может", к сожалению, оказывается правдой чаще, чем хотелось бы, потому что такой полностью автоматический подход привлекает очень много разработчиков, которые не имеют времени и/или желания разбираться со скриптованием, а полагаются на то, что фреймворк поможет им сделать это малой кровью. Поэтому они не смогут ни вовремя заметить, ни правильно исправить проблемы более низкого уровня.
Передача структурных данных
Передача структурированных данных была сутью ajax’а еще когда он назывался "XmlHttpRequest". То есть он был придуман для того, чтобы обратиться на сервер и получить описание какой-то части состояния системы, выраженной в XML — языке, который предназначен для удобной машинной обработки. Сразу скажу, что несмотря на то, что так было задумано, свет клином именно на XML-ответах не сошелся, и структуру можно передавать и по-другому, о чем чуть позже.
Плюс такого подхода — в максимальной гибкости. Можно придумать абсолютно любой формат и набор данных, который запрашивается у сервера, в котором будет в точности та информация, которой не хватает на клиенте, и ничего лишнего. На клиенте же с помощью Javascript’а можно изменить страницу полностью и как угодно.
Взять тот же пример с комментариями: на сервер отправляется комментарий, а в ответ возвращается например такое:
<comment status="ok" quantity="12"/>
Что означает, что комментарий прошел валидацию, и теперь их на странице 12. Все остальное можно сделать скриптом: пририсовать новый блок комментария, перекопировать туда текст формочки, фомочку удалить, обновить количество новой цифрой.
Самый очевидный минус в передаче структуры — это гораздо больший объем и сложность программирования. Причем складывается она из нескольких вещей.
Первая сложность — это использование XML’а. Несмотря на то, что формат четкий и замечательный, в Javascript’е с ним можно работать только с помощью методов DOM. А это муторно писать и очень сложно читать: слишком много текста для производства простых вещей. К счастью, этот конкретный недостаток в последнее время решился с помощью формата JSON: данные возвращаются с сервера не в виде XML, а в виде куска Javascript’ового кода создающего объект нужной вам структуры:
response = { status: 'ok', quantity: 12 }
Он тут же в скрипте выполняется eval’ом и вы получаете объект response, у которого есть response.status и response.quantity. Очень удобно и без всяких
getElementsByTagName('response')[0].
Кроме убирания сложности разбора XML-ответа, остается вторая сложность: построение HTML полностью вручную DOM-методам, что, опять-таки, трудно и муторно.
Но самое плохое, что этим самым в системе появляются два совершенно разных места, в которых задается вид страницы: HTML-шаблон и Javascript’овый код. А значит изменения придется аккуратно дублировать и там, и там. И еще это значит, что для написания HTML’а вам теперь нужен человек, который умеет писать и HTML, и тяжелый Javascript. "Maintenance hell", иными словами.
Вообще, когда я начинал играться с XmlHttpRequest’ом, такой подход казался мне самым естественным: раз штука умеет парсить XML, значит это и есть правильный путь ее использования. Результатом тех упражнений стал довольно прикольный клиентский ajax-интерфейс к чату с множеством всяких фенечек. Тогда, в 2003 году, он был жутко передовым технологически, но раскрутить его во что-то известное мы так и не сподобились. Я даже удивился сейчас, что он до сих пор работает. Пусть теперь тут ссылочка для истории лежит :-)
Объединение лучших черт Та несовместимость, о которой говорит Фрэнк Соммерс, присутствует только с точки зрения программиста, который выбирает передачу HTML, и не хочет погружаться в скриптование вообще. Однако если программист не против этого принципиально, то передачу структуры вполне можно объединить с передачей HTML’а. Принцип, на самом деле, очень простой:
* ответ с сервера передается в виде JSON-объекта * вещи, не связанные с генерацией HTML (например подвинуть что-то куда-то, скрыть/открыть и т.д), выполняются скриптом, используя для этого данные из объекта * если нужно менять какие-то нетривиальные куски HTML, то они передаются строками в том же самом объекте и вставляются куда надо * изменяемые части HTML на сервере оформляются как небольшие включаемые шаблончики, и используются и при начальном формировании страницы, и в ajax-ответах
Другими словами, вся "великая идея" заключается в том, что надо отказаться от догмы "пользоваться только XML’ом" и пользоваться тем, чем удобно.
Единственное, что мне пока не нравится в этом подходе, это то, что на серверной стороне несколько увеличивается объем работы. Если без ajax’а код, обслуживающий POST в форму, отдает всего два ответа — либо эту же форму с ошибками, либо редирект, когда все хорошо — то с ajax’ом к каждому ответу прибавляется еще вариант с выдачей JSON-объектов. Не особенно трудно, но выглядит слишком нагроможденно. Хотя со временем я надеюсь придумать или подсмотреть какую-нибудь автоматизацию этому процессу.
|