FL.ru – фриланс сайт удаленной работы №1. Поиск удаленной работы, фрилансеры.

Технология AJAX: будущее веб-приложений уже наступило

Категории: Вебмастеру

Все мы видели «динамичные» веб-страницы, на которых изменяется содержимое без перезагрузки самой страницы.

Долгое время такая «магия» была недоступна программистам, для подгрузки данных с сервера применялись исключительно технологии, связанные с перезагрузкой страниц с изменением параметров запросов.

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

Простой пример. Возьмем пару строк ХТМЛ-кода:

1
2
<div id="target"></div>
<p><a href="#" class="ajaxtrigger">Let there be AJAX magic</a></p>

И добавим в них jQuery-код (технология, основанная на AJAX):

1
2
3
$('.ajaxtrigger').click(function(){
  $('#target').load('ajaxcontent.html');
});

В результате этого опыта вы можете наблюдать, как ХТМЛ-документ подгружается в определённый ID «на лету», без перезагрузки.

Технология AJAX

Это технология подгрузки информации с сервера внутри java-скриптов. Если раньше java-скприпт имел доступ только к непосредственному загруженному содержимому веб-страницы, то теперь, при помощи технологии AJAX, появилась возможность обращаться с запросами к серверу непосредственно из кода джава-скрипта. Суть технологии заключается в том, что вместо полной перезагрузки всей страницы можно подгружать только ее части. Таким образом повышается интерактивность, уменьшается траффик, а также появляются новые возможности для кодинга.

Классическая система построения веб-приложений подразумевает введение пользователем адреса страницы с набором параметров, передаваемых методами GET (Набор параметров после «знака вопроса» в адресной строке) или POST. Браузер обращается к серверу с этим запросом, получает ответ и расшифровывает его. Если это ХТМЛ-документ, он отображает его на экране. Таким образом, каждое действие пользователя приводит к полной загрузке всего кода страницы с сервера.

При помощи AJAX мы можем немного упростить схему: к серверу отправляются запросы, ответами на которые будут не целые веб-страницы, а их фрагменты или стандартизированные коды, которые веб-приложение конвертирует в наглядный вид при помощи скриптов на клиентской стороне. К примеру, у нас есть форма, где данные отображаются в таблице. С помощью аякс-запроса можно получить данные с сервера в виде XML-пакета, а джава-скрипт на странице «разберет» этот код и превратит в табличный вид.

Однако с этой технологией нужно быть весьма осторожным, так как большие возможности несут за собой большие потенциальные проблемы. Рассмотрим, что нужно учитывать.

Правила хорошего тона при использовании AJAX

Необходимо убедиться, что ваши AJAX-запросы не мешают стабильной работе браузера, а также не нарушают работу вашего веб-приложения. Простой пример:

1
2
<div id="target"></div>
<p><a href="#" class="ajaxtrigger">Let there be AJAX magic</a></p>

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

1
2
3
4
<div id="target"></div>
<p><a href="ajaxtest-fullpage.html" class="ajaxtrigger">
  Let there be AJAX magic
</a></p>

Кроме того, нужно защититься от ошибки джава-скрипта. Изменим и другую часть кода:

1
2
3
4
5
$('.ajaxtrigger').click(function(){
  var url = $(this).attr('href');
  $('#target').load(url);
  return false;
});

Теперь мы не задаем параметры для открытия URI, а просто читаем параметр href из ссылки. Строка return false защитит нас от того, чтобы браузер следовал по ссылке, после обработки аякс-запроса при помощи jQuery.

Возникает еще одна проблема. В нашем примере мы подгружаем внешний документ, однако данный документ может представлять собой полноценный ХТМЛ-файл с хедерами и типовой структурой. В результате отработки аякс-запроса, весь этот код окажется на странице, повредив структуру изначального ХТМЛ-документа.

Изменим ajaxtest-fullpage.html следующим образом:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
< !DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
  [... some links and title and so on ...]
</head>
<body>
<div id="doc" class="yui-t7">
  <div id="hd" role="banner"><h1>Excerpt from Alice's Adventure Underground</h1></div>
  <div id="bd" role="main">
    <blockquote cite="http://ia341030.us.archive[...]-h.htm">
      <p>Alice was beginning to get very tired of sitting by her sister on the bank, and of having nothing to do: once or twice she had  peeped into the book her sister was reading, but it had no pictures or conversations in it, and where is the use of a book, thought Alice, without pictures or conversations? So she was considering in her own mind, (as well as she could, for the hot day made her feel very sleepy and stupid,) whether the pleasure of making a daisy-chain was worth the trouble of getting up and picking the daisies, when a white rabbit with pink eyes ran close by her.</p>
    </blockquote>
    <p>Excerpt taken from
      <a href="http://ia341030.us.archive[...]-h.htm">archive.org</a>.
    </p>
  </div>
  <div id="ft" role="contentinfo">
    <p>Demo by <a href="http://wait-till-i.com">Chris Heilmann</a></p>
  </div>
</div>
</body>
</html>

В инструментарии jQuery есть возможность вырезать необходимые элементы по определенным селекторам, это учтено в функции load().

1
2
3
4
5
$('.ajaxtrigger').click(function(){
  var url = $(this).attr('href');
  $('#target').load(url+' #bd blockquote');
  return false;
});

С помощью данного кода мы подгружаем только блок с идентификатором «blockquote», избавившись от попадания на страницу целого хтмл-документа со всеми хедерами.

Однако тут возникает вопрос: зачем грузить целую страницу, а потом ее обрезать, если можно сразу «попросить» у сервера обрезанный вариант. Для этого нужно прибегнуть к инструментарию РНР и кое-что подправить на серверной стороне. При помощи параметра $_SERVER[‘HTTP_X_REQUESTED_WITH’] можно выяснить, пришел ли запрос из аякса или обычным методом




1
2
3
4
5
6
7
< ?php if($_SERVER['HTTP_X_REQUESTED_WITH']=='XMLHttpRequest'){?>
This is content requested by AJAX.
< ?php }?>
 
< ?php if($_SERVER['HTTP_X_REQUESTED_WITH']==''){?>
This is the normal content requested in a browser
< ?php }?>

Вот пример страницы, которая генерируется на сервере по-разному, для обычного браузера и аякс-загрузчика

1
2
3
4
5
6
7
8
9
10
11
12
13
14
< ?php if($_SERVER['HTTP_X_REQUESTED_WITH']==''){?>
  include('header.php');
< ?php }?>
 
<blockquote cite="http://ia341030.us.archive[...]-h.htm">
  <p>Alice was beginning to get very tired of sitting by her sister on the bank, and of having nothing to do: once or twice she had peeped into the book her sister was reading, but it had no pictures or conversations in it, and where is the use of a book, thought Alice, without pictures or conversations? So she was considering in her own mind, (as well as she could, for the hot day made her feel very sleepy and stupid,) whether the pleasure of making a daisy-chain was worth the trouble of getting up and picking the daisies, when a white rabbit with pink eyes ran close by her.</p>
</blockquote>
<p>Excerpt taken from
  <a href="http://ia341030.us.archive[...]-h.htm">archive.org</a>.
</p>
 
< ?php if($_SERVER['HTTP_X_REQUESTED_WITH']==''){?>
  include('footer.php');
< ?php }?>

Такой подход к применению данной технологии имеет ряд преимуществ:

1. Вы точно будете уверены в валидности ваших ссылок
2. Вам больше не придется выслеживать URI в скриптах, все данные находятся непосредственно в ХТМЛ
3. Пользователи смогут открывать ссылки в новых вкладках, где они будут выглядеть нормально
4. Можно размещать содержимое как на основе аякс-технологии, так и без нее.

Существуют методы, которые позволяют делать AJAX-приложения максимально безопасными и устойчивыми. Главное, что нужно учитывать при разработке приложений: безопасности нужно уделять внимание сразу, по ходу разработки. Существует два широко распространенных метода: «Ненавязчивый javascript» и Hijax. С их помощью можно добиться максимальной устойчивости и безотказности, но только если следовать этим методам от самого начала разработки.

Сложности дизайна под AJAX

Аякс-технология накладывает отпечаток на интерфейс любых веб-приложений. Теперь нужно не только обращать внимание на общий вид страницы, но придавать значение каждому элементу. Всегда нужно предполагать, как страница будет выглядеть без джава-скрипта. При помощи AJAX-интерфейсов можно строить веб-приложения, которые практически не ограничены по дизайну и в них могут воплотиться самые дикие концепции.

Необходимо учитывать особенности пользования интернетом, и имитировать для пользователя привычные функции браузера. Этот список довольно объемен:

1. Полоса загрузки страницы, которую при аякс-загрузке нужно заменять анимированной иконкой.
2. Возможность прерывания загрузки страницы при помощи кнопки «стоп»
3. Обработка ошибок в том случае, если загружаемая страница не может быть найдена
4. Обработка различных состояний страницы (необходимость авторизации и т.п.)
5. Возможность открыть любую ссылку на новой вкладке
6. Возможность добавить адрес страницы в закладки
7. Наличие кнопки «назад», возвращающей к предыдущему окну

Чтобы пользователю было удобно работать с вашим AJAX-приложением, все эти функции должны присутствовать.

Делаем наглядным процесс загрузки

Кликнув по ссылке, пользователь ждет немедленного ответа системы. Хотя бы подтверждения того, что какой-то процесс пошел. Если система не ответила – человек может кликнуть еще и еще раз. Для аякс-приложения это нежелательно.

Реализуется оповещение о загрузке следующим образом:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$(document).ready(function(){
  var container = $('#target');
  $('.ajaxtrigger').click(function(){
    doAjax($(this).attr('href'));
    return false;
  });
  function doAjax(url){
    $.ajax({
      url: url,
      success: function(data){
        container.html(data);
      },
      beforeSend: function(data){
        container.html('<p>Loading...</p>');
      }
    });
  }
});

Ошибки

Аякс-приложение должно правильно реагировать на возможные ошибки при выполнении запросов. С помощью следующего скрипта обрабатываются самые распространенные ошибки:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
$(document).ready(function(){
  var container = $('#target');
  $('.ajaxtrigger').click(function(){
    doAjax($(this).attr('href'));
    return false;
  });
  function doAjax(url){
    if(url.match('^http')){
      var errormsg = 'AJAX cannot load external content';
      container.html(errormsg);
    } else {
      $.ajax({
        url: url,
        timeout:5000,
        success: function(data){
          container.html(data);
        },
        error: function(req,error){
          if(error === 'error'){error = req.statusText;}
          var errormsg = 'There was a communication error: '+error;
          container.html(errormsg);
        },
        beforeSend: function(data){
          container.html('<p>Loading...</p>');
        }
      });
    }
  }
});

Подсветка изменений

При помощи аякса можно подсвечивать изменения, возникшие на странице. Для этого можно применить плагин jQuery Highlight. Вот пример его внедрения в код:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
$(document).ready(function(){
  var container = $('#target');
  $('.ajaxtrigger').click(function(){
    doAjax($(this).attr('href'));
    return false;
  });
  function doAjax(url){
    if(url.match('^http')){
      var errormsg = 'AJAX cannot load external content';
      container.html(errormsg).
        effect('highlight',{color:'#c00'},1000);
    } else {
      $.ajax({
        url: url,
        timeout:5000,
        success: function(data){
          container.html(data).
            effect("highlight",{},1000);
        },
        error: function(req,error){
          if(error === 'error'){error = req.statusText;}
          var errormsg = 'There was a communication error: '+error;
          container.html(errormsg).
            effect('highlight',{color:'#c00'},1000);
        },
        beforeSend: function(data){
          container.html('<p>Loading...</p>');
        }
      });
    }
  }
});


AJAX и проблемы юзабилити

Вместе с удобством AJAX приносит существенное изменение и усложнение интерфейса. Так, пользователь может не уследить за изменениями на странице, не разобраться с тем, где и как открывается контент, не разобраться в элементах управления на странице и т.п. Чтобы не ставить пользователей в тупик, нужно учитывать всё это в своем коде.

Пользователи со слабым зрением

Есть специальные системы, называемые «экранными читалками». Это приложения, которые обрабатывают хтмл-страницу и подают ее в таком виде, чтобы пользователю со слабым зрением было удобно ее читать. Обработчики часто не дружат с аяксом, потому, если приложение проектируется под людей со специальными потребностями, необходимо уделить этому внимание и научить свое аякс-приложение «общаться» с читалками.

Управление клавиатурой

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

Обозначение изменений

Пользователь должен понимать, что происходит на странице. Для этого все запросы должны сопровождаться различными индикаторами, оповещениями. Пользователь должен иметь четкое представление о том, что делается на странице.

На примере следующего кода вы можете разобраться, как делаются эти доработки на практике

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
$(document).ready(function(){
 
  // this is the container we'll load content into
  var container = $('#target');
 
  // adding a tabIndex of -1 makes it keyboard accessible,
  // and we can set the focus to it
  container.attr('tabIndex','-1');
 
  // if a user clicks on an element with the class ajaxtrigger...
  $('.ajaxtrigger').click(function(){
 
    // define trigger as the link
    var trigger = $(this);
 
    // read its href attribute (which is the URI we'll load with AJAX)
    var url = trigger.attr('href');
 
    // if the element does not have a class called "loaded"
    if(!trigger.hasClass('loaded')){
 
      // add a new span to the element.
      trigger.append('<span></span>');
 
      // add a class called 'loaded' to the element
      trigger.addClass('loaded');
 
      // and define msg as the last span in the element
      var msg = trigger.find('span::last');
 
    // otherwise, simply define msg as the last span in the element
    } else {
      var msg = trigger.find('span::last');
    }
    // ^ this condition means we only add the span once and not
    //   every time users click the element.
 
    // call the doAjax function with the URI to load,
    // the span inside the link to change and the
    // target element to replace.
    doAjax(url,msg,container);
 
    // tell the browser to not follow the link
    return false;
  });
 
  // here's where the AJAX magic happens
  function doAjax(url,msg,container){
 
    // if the URI starts with http...
    if(url.match('^http')){
      // show an error and set the class of the span to 'error'
      msg.html(' (error!)').addClass('error');
 
      // tell the end user in the target element what the error is
      var errormsg = 'AJAX cannot load external content';
 
      // update the container with the error
      updateContainer(errormsg,'#c00');
 
    // if the URI does not start with http
    } else {
 
      // start an AJAX request using the url
      $.ajax({
        url: url,
 
        // give the request five seconds time, otherwise call it
        // a timeout error
        timeout:5000,
 
        // if all went well
        success: function(data){
 
          // set the span content to ready
          msg.html(' (ready.)');
 
          // update the container with the right data
          updateContainer(data,'#ff9');
        },
 
        // if there was an error
        error: function(req,error){
 
          // say in the link that there was an error and set the
          // class of the span to 'error'
          msg.html(' (error!)').addClass('error');
 
          // if the error just says error, get the real status
          // text from the browser (jQuery doesn't do this right)
          if(error === 'error'){error = req.statusText;}
 
          // tell the user that there is a communication error
          var errormsg = 'There was a communication error: '+error;
 
          // update the container with the error
          updateContainer(errormsg,'#c00');
        },
 
        // if the link was clicked but the AJAX request was not fired...
        beforeSend: function(data){
 
          // remove any "error" classes and set the span message to loading
          msg.removeClass('error').html(' (loading...)');
        }
      });
    }
  };
 
  // update the container
  function updateContainer(content,colour){
    container.
      // set the content
      html(content).
        // shift the browser focus
        focus().
          // flash the container for a second in the
          // specified colour
          effect('highlight',{color:colour},1000);
  }
 
});

Порядок в интерфейсе

Интерфейс должен разрабатываться таким образом, чтобы он был прост и понятен. Не нужно делать аякс ради аякса, каждый такой элемент управления должен добавлять простоты и понятности. Если же в тексте вполне достаточно обычной «традиционноый» гиперссылки, лучше в таком виде ее и сделать. Простые и легкие интерфейсы – это самые лучшие и надежные интерфейсы. Всегда помните, что пользователи приходят на сайт за функционалом и информацией, а не для оценки технических наворотов.

Противопоказания AJAX

Есть ряд случаев, когда технологию AJAX применять не стоит. Рассмотрим их:

1. Не стоит его применять, если речь идет о чувствительной или конфиденциальной информации. Траффик, идущий через AJAX, может быть перехвачен.
2. Излишеством является аякс в том случае, если на вашем сайте нет сложного веб-приложения, а просто размещены статьи (к примеру, это блог). Все-таки аякс лучше подходит для сложных веб-форм и приложений.
3. Если вам важна поисковая оптимизация – об аяксе лучше забыть. Роботы не индексируют динамично подгружаемое содержимое, потому ваша аякс-страница не будет индексирована, как следует.

Показания для применения AJAX

1. Если на вашей странице обрабатывается большое количество маленьких порций данных.
2. Если вы хотите дать пользователям возможность мгновенной оценки (рейтинг, звездочки и т.п.)
3. Для динамичной подгрузки постоянно меняющегося контента.

Для сложных веб-приложений, которым нужен особенный интерфейс.

На десерт: Как примененяется ajax на крупных сайтах




Подпишитесь на рассылку блога
max1net.com:
Уже подписались человек
Укажите свой e-mail