Internet Explorer 8
Новые функции для веб-фрагментов, хранения и повышения производительности веб-приложений
Дарон Йондем (Daron Yöndem)
Загружаемый файл с кодом доступен в коллекции кода MSDN
Обзор кода в интерактивном режиме
В этой статье рассматриваются следующие вопросы.
|
В этой статье используются следующие технологии: AJAX, JavaScript |
Эта статья основана на предварительной версии Internet Explorer 8. Любые приведенные в ней сведения могут быть изменены.
Содержание
Выделение областей страниц с помощью веб-фрагментов
Окончание сроков действия и частота обновлений
Ускорители
Варианты поиска
Навигация AJAX
Хранилище DOM
Автономный и сетевой режимы работы
Тайм-ауты XMLHttpRequest
Заключение
Internet Explorer 8 представляет собой большой шаг вперед в эволюции продукта. Для конечного пользователя предоставлена новая функциональность, такая как веб-фрагменты, ускорители и варианты поиска; разработчики найдут в нем более сложные функции, такие как навигация AJAX и хранилище DOM.
В этой статье я расскажу о каждом из этих компонентов, чтобы показать, как Internet Explorer 8 может упростить жизнь и разработчикам, и пользователям. Будет показано, как эти новые возможности позволяют определять части страницы, управлять частотой обновлений и сроком их действия, облегчать пользователю поиск и навигацию и так далее.
Выделение областей страниц с помощью веб-фрагментов
Веб-фрагменты позволяют разделить страницу на части, отображая и обновляя только те части, которые нужно. Веб-фрагменты могут быть удобным решениям для пользователя, который желает получать последние обновления с веб-сайта, но не желает использовать средство чтения RSS. Средства чтения RSS могут показаться сложными для некоторых конечных пользователей; кроме того, они не всегда подходят.
Веб-фрагменты – это программно заданные части веб-страницы, о которых пользователи узнают, наведя на них курсор или щелкнув кнопку «Подписаться на этот веб-фрагмент» на панели инструментов. На рис. 1 это показано в действии.

Рис. 1. Обнаружение веб-фрагмента наведением курсора
После подписки на веб-фрагмент пользователь сможет увидеть его название на панели «Избранное» Internet Explorer 8. Internet Explorer будет поддерживать связь с источником информации и уведомлять пользователя об обновлениях, выделяя заголовок фрагмента жирным шрифтом. При щелчке заголовка содержимое фрагмента будет показано во всплывающем окне, как показано на рис. 2.

Рис. 2. Поиск последнего предложения на аукционе в веб-фрагменте
Одним из крупных достоинств веб-фрагментов является то, что они избавляют пользователей от необходимости обновлять веб-страницу для отслеживания изменений на сайте. Более того, в зависимости от структуры источников данных для веб-фрагментов они могут помочь сэкономить ресурсы веб-сервера, поскольку обновляться будут только относящиеся к веб-фрагментам данные, а не вся страница. Кроме того, использование веб-фрагментов позволяет системе предоставлять более подробные данные о доступе пользователей к различным частям веб-страницы, что может помочь в принятии последующих решениях при разработке.
Как я упоминал ранее, веб-фрагменты определяются разработчиком заранее. Так как же это делается? В самую первую очередь, необходимо пометить элемент HTML div как контейнер, содержащий веб-фрагмент. Для этого используется имя класса hslice. В элементе hslice будут находиться все остальные определения, необходимые для веб-фрагмента. Вот определение пустого веб-фрагмента:
<div class="hslice" id="ProductID1"> </div>
Каждый веб-фрагмент должен иметь уникальный идентификатор, поскольку именно с его помощью Internet Explorer различает веб-фрагменты на странице. Если идентификатор веб-фрагмента изменится после того, как пользователи на него подпишутся, Internet Explorer не сможет его найти и обновлять содержимое панели «Избранное» станет невозможно.
В каждом веб-фрагменте должен быть элемент для определения заголовка фрагмента. Это название определяется по классу CSS entry-title. Именно такой заголовок будет показан на панели «Избранное» и в меню командной панели поиска каналов. Если потребуется, то текст entry-title можно изменить; он обновится вместе с обновлением веб-фрагмента.
Давайте завершим создание первого веб-фрагмента добавлением еще одного элемент: класса содержимого записи (entry-content). Сам веб-фрагмент и его заголовок уже определены, но в нем пока нет содержимого, которое можно было бы показать пользователю. Определим содержимое веб-фрагмента, применив класс CSS entry-content к тому содержимому, которое должно отображаться пользователю:
<div class="hslice" id="ProductID1">
<h1 class="entry-title">
Brand New Product!</h1>
<div class="entry-content">
<p>
This is the product
definition.</p>
</div>
</div>
Определение веб-фрагмента показано на рис. 3. Веб-фрагмент называется ProductID1, у него есть заголовок и содержимое.

Рис. 3. Простой веб-фрагмент
Обогатить пользовательское взаимодействие с веб-фрагментом можно при помощи визуальных элементов и встроенных (или глобальных) стилей CSS. Единственное ограничение состоит в невозможности применять сценарии или элементы управления ActiveX (включая Silverlight). Если ActiveX необходим, то придется использовать другой источник отображаемой информации. Его можно будет определить в элементе-контейнере entry-content веб-фрагмента.
Как показано здесь, помещать содержимое внутрь элемента entry-content необязательно. Достаточно перенаправить веб-фрагмент и сообщить браузеру, что содержимое поступит с другого URL-адреса:
<div class="hslice" id="ProductID2">
<h1 class="entry-title">
Brand New Product</h1>
<div class="entry-content" href="https://www.contoso.com/web_slice/
alternative_display.aspx?ID=2">
</div>
</div>
Тем самым появляется возможность отследить, сколько раз обновлялся каждый веб-фрагмент и сколько пользователей просматривает те или иные веб-фрагменты, просто отслеживая страницы-источники содержимого. Кроме того, на целевой странице alternative_display.aspx допустимо использование элементов управления ActiveX.
Окончание сроков действия и частота обновлений
Порой необходимо, чтобы срок действия веб-фрагмента закончился вовремя, даже если пользователь работает в автономном режиме и веб-фрагмент не может быть обновлен. Это особенно верно для сайтов, содержащих сетевые аукционы или сетевые кампании по сбыту. Установить время, после которого веб-фрагмент станет недействительным, можно добавлением имени класса endtime и соответствующих значений даты и времени внутрь элемента сокращения HTML, как показано ниже:
<div class="hslice" id="ProductID1">
<h1 class="entry-title">
Brand New Product!</h1>
<div class="entry-content">
<p>
This is the product definition.</p>
<p>
This is the end time:
<abbr class="endtime" title="2008-10-12T11:00:00-12:00:00">
12:00</abbr></p>
</div>
</div>
Пользователи могут установить частоту обновлений, щелкнув правой кнопкой мыши заголовок веб-фрагмента на панели «Избранное» и выбрав команду «Свойства». Как показано на рис. 4, можно задавать настраиваемые расписания обновлений.

Рис. 4. Пользователи могут устанавливать частоту обновлений веб-фрагмента
Кроме того, частоту обновлений можно указывать не только в определенных пользователем параметрах, но и программно, указывая значения срока жизни (ttl):
<div class="hslice" id="ProductID6">
<h1 class="entry-title">
Brand New Product!!!!</h1>
<div class="entry-content">
<p>
This is the product definition.</p>
<div class="ttl" style="display: none;">
15</div>
</div>
</div>
Чтобы задать частоту, я создал элемент DIV с классом CSS ttl и содержимым 15. Это дает браузеру указание проверять возможные обновления в содержимом веб-фрагмента каждые 15 минут. Обратите внимание на то, что я сознательно сделал элемент DIV невидимым, установив значение параметра CSS display в none.
Как я уже упоминал, можно использовать альтернативные источники данных, но иногда полезно просто указать веб-фрагменту, чтобы данные извлекались из внешнего источника. Существуют два варианта использования внешних источников данных. Один вариант– использовать внешний веб-фрагмент на другой странице, как показано в следующем фрагменте кода.
<div class="hslice" id="ProductID10">
<div class="entry-title">
Product Name
</div>
<a rel="feedurl" href="https://www.contoso.com/
external.aspx#ProductID1"></a>
</div>
В соответствии с этим определением веб-фрагмента другой веб-фрагмент должен быть извлечен из external.aspx. Целевой веб-фрагмент обнаруживается по его идентификатору (ProductID1) и присоединяется к URL-адресу. Наличие атрибута rel в теге anchor указывает Internet Explorer использовать URL-адрес тега anchor как источник данных веб-фрагмента, а не отображать его содержимое в теге div.
Другой вариант – использовать внешний RSS-канала. Internet Explorer всегда использует первый элемент внутри канала RSS и показывает содержимое записи из входящего XML RSS-канала:
<div class="hslice" id="ProductID10">
<div class="entry-title">
Product Name
</div>
<a rel="feedurl" href="/slicefeed.xml"></a>
</div>
Здесь у веб-фрагмента есть тег привязки feedurl, направленный на источник XML, которую легко заменить универсальным обработчиком, выдающим XML динамически, в зависимости от того или иного параметра. Источник XML для нашего примера показан здесь:
<?xml version="1.0" encoding="utf-8" ?>
<rss version="2.0">
<channel>
<title>WebSlice RSS</title>
<ttl>120</ttl>
<item>
<title>Product Name Here</title>
<description>HTML <b>codes</b> can be used</description>
</item>
</channel>
</rss>
Вместо определения параметров веб-фрагмента в HTML-коде с помощью класса entry-content, их можно определить в источнике данных XML. В предыдущем коде источник XML предоставлял значения для свойств веб-фрагмента ttl и title. В теге description, не вызывая никаких проблем, может находиться форматирование HTML.
Ускорители
Ускорители существуют для того, чтобы некоторые распространенные задачи при просмотре сети выполнялись быстрее, а степень их автоматизации повышалась. Подумайте о том, как часто пользователям приходится копировать содержимое с одного веб-сайта на другой. Предположим, что пользователь нашел нужный ему адрес на веб-сайте корпорации и теперь хочет узнать, как туда проехать. Он копирует адрес в буфер, запускает веб-сайт Live Maps и вставляет адрес в поле на сайте. Этот процесс можно автоматизировать с помощью ускорителя.
На рис. 5 показан ускоритель, который находит местоположение на карте того адреса, который щелкнул пользователь. Написать свой ускоритель несложно. Разработчику нужно только определить, что будет делать ускоритель, с помощью XML-файла OpenService Description. Давайте подробнее рассмотрим формат OpenService Description. Ниже показан простой файл в формате OpenService Description:
<?xml version="1.0" encoding="utf-8" ?>
<openServiceDescription xmlns="https://www.microsoft.com/schemas/
openservicedescription/1.0">
<homepageUrl>https://www.contoso.com/</homepageUrl>
<display>
<name>Translate it with Contoso</name>
<icon>https://www.contoso.com/favicon.ico</icon>
</display>
<activity category="translate">
...
</activity>
</openServiceDescription>

Рис. 5. Ускоритель Live Maps позволяет мгновенно найти положения на карте
Основные свойства ускорителя – это теги homepageUrl, display и activity. homepageUrl – это URL-адрес предоставляемой службы. Все URL-адреса, используемые в других тегах и параметрах, должны использовать тот же домен, что и homepageUrl. Тег display определяет, как выглядит кнопка ускорителя в меню щелчка правой кнопкой мыши Internet Explorer. При щелчке страницы правой кнопкой мыши будут показаны название и значок ускорителя.
Элемент activity определяет, какую услугу предоставляет ускоритель. В данном примере ускоритель выполнит перевод. Можно контролировать то, в какую группу контекстного меню Internet Explorer поместит ускоритель, используя различные категории, такие как Add (для добавления ссылки), Blog (для ведения электронного журнала удаленной службы), Define (для поиска определения), Map (для поиска карты) и Translate (для перевода выбранного текста). Можно определять собственные категории. Предлагаемые правила определения категорий состоят в том, что категории должны быть обобщенными глаголами, чтобы позволить другим разработчикам ускорителей тоже их использовать.
Теперь можно определить activityActions внутри тега activity. Ниже можно увидеть один activityAction с контекстным значением selection:
<activityAction context="selection" >
<preview action="https://www.contoso.com/translateacc.aspx" method=" get" >
<parameter name="word" value="{selection}" />
</preview>
<execute action=" https://www.contoso.com/translate.aspx " method=" post" >
<parameter name="word" value="{selection}" />
</execute>
</activityAction>
Атрибут контекста – это ключевой компонент activityAction. Контекст определяет, когда действие станет доступным. Если ускоритель не предоставляет действия, подходящего для текущего контекста, оно не будет видимым в меню ускорителя в Internet Explorer. Возможные варианты текущего контекста – selection и link. Если контекст – selection, то пользователю необходимо выбрать текст и перейти к меню ускорителя, чтобы использовать ускоритель. Если контекст – link, то для запуска действия пользователю следует щелкнуть гиперссылку правой кнопкой мыши.
В каждом activityAction могут присутствовать определения действий и предварительного просмотра. Действие (Execute) запускается, когда пользователь щелкает команду ускорителя из меню ускорителей. Действие предварительного просмотра (Preview) запускается, когда пользователь наводит и задерживает указатель мыши над командой ускорителя в меню. Как в теге Preview, так и в теге Execute могут быть URL-адрес действия и метод. В качестве методов передачи данных можно использовать GET или POST.
Параметры для каждого действия определяются в виде пар имя/значение. Значения автоматически задаются ключевыми словами в фигурных скобках. Например, {selection} означает, что выбранный пользователем текст будет значением связанного с ним параметра. Список возможных ключевых слов показан на рис. 6.
| Рис. 6. Ключевые слова |
| Название | Описание |
| documentDomain | Адрес домена текущей страницы. |
| documentTitle | Заголовок текущей страницы. |
| documentUrl | Полный URL-адрес текущей страницы. |
| link | Если пользователь щелкает ссылку, передается полный адрес ссылки. |
| linkDomain | Если пользователь щелкает ссылку, передается адрес домена ссылки. |
| linkRel | Если пользователь щелкает ссылку, передается значение свойства rel ссылки. |
| linkText | Если пользователь щелкает ссылку, передается текст ссылки. |
| selection | Выбранный текст на текущей странице. |
Окно предварительного просмотра работает как IFrame, а это значит, что внутри него можно использовать все виды взаимодействия. Более подходящим решением может быть разработка конкретного интерфейса и выделение URL-адресов для выполнения действий и предварительного просмотра.
Завершающий данный пример файл в формате OpenService Description показан на рис. 7. Теперь посетитель веб-сайта должен установить этот ускоритель на свой ПК. Вот сценарий, необходимый для установки ускорителя:
<div>
<input id="Button1" type="button"
value="Click to Install"
onclick="window.external.AddService('myaccelerat.xml');" />
</div>
Рис. 7. Последний файл OpenService Description
<?xml version="1.0" encoding="utf-8" ?>
<openServiceDescription xmlns="https://www.microsoft.com/schemas/
openservicedescription/1.0">
<homepageUrl>https://www.contoso.com/</homepageUrl>
<display>
<name>Translate with Contoso</name>
<icon>https://www.contoso.com/favicon.ico</icon>
</display>
<activity category="translate">
<activityAction context="selection" >
<preview action="https://www.contoso.com/translate.asp">
<parameter name="Word" value="{selection}" />
</preview>
<execute action="https://www.contoso.com/translate.asp">
<parameter name="Word" value="{selection}" />
</execute>
</activityAction>
</activity>
</openServiceDescription>
Метод AddService получает URL-адрес XML-файла OpenService Description и начинает установку. Чтобы проверить, не был ли установлен ускоритель раньше, можно вызвать метод isServiceInstalled.
Варианты поиска
В Internet Explorer 7.0 появился новый компонент под названием поставщики поиска. Пользователи получили возможность интегрировать различные поставщики поиска в браузер и использовать панель поиска для легкого перехода к своей любимой поисковой подсистеме. Это стало возможным благодаря файлам спецификации OpenSearch на основе XML. С помощью возможности, которая называется «варианты поиска», Internet Explorer 8 упрощает поиск еще больше. Как и предполагает название, браузер предлагает варианты при вводе слова поиска.
По мере набора слова пользователем браузер обращается к выбранному провайдеру вариантов поиска и запрашивает варианты, относящиеся к введенным словам поиска. Пользователь видит полученные данные, тем самым поиск упрощается (см. рис. 8).

Рис. 8. Простой доступ к вариантам искомых слов без необходимости покидать текущую страницу
Прежде чем в подробностях рассказать о работе вариантов поиска, необходимо определить поставщика поиска. Поставщик поиска состоит из трех элементов: названия, поискового URL-адреса и значка. Все они определены в XML-спецификации OpenSearch. Ниже приведен полнофункциональный поставщик поиска, написанный для Internet Explorer 7.0 – без вариантов поиска:
<?xml version="1.0" encoding="UTF-8"?>
<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/">
<ShortName>Contoso Search</ShortName>
<Url type="text/html" template="https://www.contoso.com/?key2search=
{searchTerms}"/>
<Image height="16" width="16" type="image/icon">
https://www.contoso.com/favicon.ico</Image>
</OpenSearchDescription>
Тег ShortName содержит название поставщика поиска, а тег URL определяет поисковый путь подсистемы поиска. Ключевое слово searchTerms в шаблоне URL будет заменено словами, которые ищет пользователь. Тег Image указывает на файл значка для поставщика поиска.
Для установки поставщика поиска пользователь должен будет щелкнуть элемент HTML на странице или найти поставщик поиска с помощью окна поиска Internet Explorer 8. Как и ускорители, поставщики поиска можно устанавливать с помощью функции AJavaScript window.external.AddSearchProvider:
<a href="#" onclick="window.external.AddSearchProvider('http://
www.contoso.com/provider.xml')"> Add Search Provider </a>
Обратите внимание на то, что функция JavaScript AddSearchProvider требует URL-адрес XML-файла OpenSearch в качестве параметра.
Вместо прямой ссылки на XML-файл OpenSearch браузер может попытаться найти поставщик поиска на веб-странице. Чтобы поставщик поиска нашелся, необходимо поместить скрытую ссылку на XML-файл OpenSearch в HTML заголовка страниц. Вот скрытая ссылка, указывающая на поставщик поиска:
<link title="Contoso Search" rel="search" type="application/
opensearchdescription+xml" href="https://www.contoso.com/provider.xml" />
Название ссылки – это название подсистемы поиска, которое будет показано в браузере. Свойства rel и type должны быть точно такими же, как указанные здесь. Так браузер распознает ссылку как указатель на поставщик поиска. Атрибут href содержит URL-адрес XML-файла описания OpenSearch.
Теперь, когда поставщик поиска готов, можно добавлять к нему варианты поиска. Во-первых, необходимо изменить XML-файл описания OpenSearch и указать источник данных для вариантов поиска:
<?xml version="1.0" encoding="UTF-8"?>
<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/">
<ShortName>Contoso Search</ShortName>
<Url type="text/html" template="https://www.contoso.com/?key2search=
{searchTerms}"/>
<Url type="application/x-suggestions+json" template="http://
www.contoso.com/json.ashx? key2search ={searchTerms}"/>
<Image height="16" width="16" type="image/icon">http://
www.contoso.com/favicon.ico</Image>
</OpenSearchDescription>
Можно заметить, что к предыдущему файлу описания поставщика поиска добавилась одна строка XML– новый тег URL с другим значением типа. Чтобы использовать варианты поиска, необходима служба, способная оценивать искомые слова и выдавать список подходящих вариантов.
Список может быть представлен в формате XML или JSON. В данном примере я добавил указатели к службе вариантов, используя формат JSON. Тем не менее, с помощью следующего XML-файла можно легко воспользоваться службой на основе XML:
<Url type="application/x-suggestions+xml" template="http://
www.contoso.com/xml.ashx?
key2search ={searchTerms}"/>
Между источниками данных XML и JSON существуют важные различия. Источник данных JSON может предоставить список вариантов, включая предлагаемые результаты, по одному на каждый результат и, если нужно, URL-адрес. Например:
["con",
["contoso soft", "contoso books", "contoso rent"],
["software company", "book store", "rent a car"],
["https://www.contoso.com/soft", "https://www.contoso.com/books", "https://www.contoso.com/rent"]]

Рис. 10. Пример списка вариантов при поиске
Internet Explorer 8 извлечет данные JSON на ходу и тут же покажет список автозаполнения. Учтите, что искомое слово должно входить в данные, возвращаемые поставщиком. Первый элемент в примере JSON содержит искомое слово «con».
Если решено для предоставления Internet Explorer вариантов поиска использовать формат XML, то можно будет выбрать заголовок для списка результатов, разделить результаты с помощью разделителей, а также предоставить визуальные варианты.
Для начала я представлю список вариантов при поиске с двумя результатами и одним разделителем. Возвращенный XML, показанный на рис. 9, содержит искомое слово в тегах запроса (Query), а в теге Section возвращает два элемента Items. У тега Section есть заголовок, а у каждого элемента есть текст (Text), описание (Description) и URL-адрес (URL) для выполнения переходов.
Рис. 9. XML для вариантов поиска
<SearchSuggestion>
<Query>con</Query>
<Section title="First Section">
<Item>
<Text>Result 1</Text>
<Description>Description 1</Description>
<Url>https://www.contoso.com?id=1</Url>
</Item>
<Separator title="Others"/>
<Item>
<Text>Result 2</Text>
<Description>Description 2</Description>
<Url>https://www.contoso.com?id=2</Url>
</Item>
</Section>
</SearchSuggestion>
Для предоставления различных списков результатов в окне вариантов поиска можно использовать теги разделителей (separator) с заголовками. Если пользователь щелкнет предлагаемый элемент в списке, то будет использован URL-адрес. На рис. 10 можно увидеть, как данные XML будут показаны в Internet Explorer 8.
Помимо классического представления списка вариантов для улучшения взаимодействия с пользователем, можно использовать изображения, показывая его с каждым вариантом. Для этого достаточно добавить тег Image к соответствующем тегам Item:
<Item>
<Text>Result 1</Text>
<Description>Description 1</Description>
<Url>https://www.contoso.com?id=1</Url>
<Image Source=https://www.contoso.com/image.png
alt="A picture is worth thousand words" width="70"></Image>
</Item>
Навигация AJAX
AJAX – один из основных компонентов приложений Интернета с широкими возможностями и останется таковым, пока продолжает использоваться HTML. AJAX можно использовать для обновления частей интерфейса пользователя без обновления всей страницы и выполнения циклов клиент-сервер для каждого действия пользователя. Но у AJAX есть и недостатки.
Когда AJAX используется для изменения содержимого веб-страницы, можно заметить, что адресная строка не меняется. В этом есть смысл. Но что если пользователю нужен постоянный URL-адрес текущего состояния страницы, скажем, для добавления ее в избранное? Что если пользователь нажмет кнопку «Назад» в своем браузере? Тогда произойдет переход на веб-сайт, посещенный ранее.
Нужно как-то отразить изменение URL-адреса, не обновляя веб-сайт. Здесь и помогает идентификатор фрагментов. Задача идентификатора фрагментов соответствует его названию – он определяет состояние части страницы.
У каждого URL-адреса может быть идентификатор фрагмента, нужно лишь добавить знак «#» к концу URL-адреса (например, www.contoso.com/default.aspx\#5). Если изменить содержимое после знака #, веб-страница не обновится, но журнал истории браузера запишет изменение и сделает возможными переходы назад и вперед (при этом оставаясь на той же странице).
В Internet Explorer 8 такая возможность предоставляется с помощью свойства window.location.hash и нового события hashChanged. При каждом изменении свойства window.location.hash адресная строка будет обновляться и содержимое этого свойства хэша будет размещаться после знака #. При попытках пользователя перейти на другую веб-страницу с помощью кнопок браузера событие hashChanged будет запускаться и предоставлять значение хэша цели (значение после знака # целевых страниц).
Создадим простой веб-сайт с реализацией WebMethod для обслуживания вызовов AJAX. На этом веб-сайте будет кнопка HTML и элемент DIV. При каждом щелчке кнопки HTML числовое содержимое элемента DIV будет отправляться в WebMethod:
<form id="form1" runat="server">
<asp:ScriptManager EnablePageMethods="true" ID="ScriptManager1"
runat="server">
</asp:ScriptManager>
<div>
<input id="Button1" onclick="GetNext();" type="button" value="button" />
<div id="content">0</div>
</div>
</form>
Чтобы вызвать службу, добавьте следующий код JavaScript:
function GetNext() {
PageMethods.GetNext($get("content").innerHTML, Done);
}
function Done(sender) {
$get("content").innerHTML = sender;
window.location.hash = sender;
}
Наконец, создайте WebMethod в файле фонового кода страницы для увеличения значения целочисленного параметра и возвращения его AJAX:
<System.Web.Services.WebMethod()> _
Public Shared Function GetNext(ByVal x As Integer) As Integer
Return x + 1
End Function
Метод JavaScript под названием GetNext выполняет запрос XMLHttpRequest к серверу. Параметры для метода GetNext – это содержимое элемента DIV и метод обратного вызова. Когда в ответ служба вызывает метод, Done, новое значение помещается обратно в элемент DIV.
А вот теперь интересный момент. После изменения веб-страницы путем добавления нового содержимого добавим уникальный идентификатор к свойству window.location.hash, чтобы определить текущее состояние веб-страницы. Для нашего простого примера значение – это тот же номер, что отображен в элементе DIV. Если после изменения свойства хэша взглянуть в историю браузера, можно будет заметить новые записи, которые здесь не указаны.
Всякий раз, когда пользователь переходит назад или вперед по истории браузера, свойство хэша будет передано обратно функции JavaScript, обрабатывающей событие onhashchange. Этого можно добиться с помощью следующей строки кода:
<body onhashchange="HashChanged();">
Функция будет вызываться при каждом переходе пользователя назад или вперед, а Internet Explorer 8 будет обновлять свойство window.location.hash согласно значениям в истории браузера. Это позволяет легко получить значение хэша и обновить страницу, будет ли это действие сводиться к обновлению страницы с помощью самих данных хэша, как показано ниже, или включать в себя запрос данных сервера на основе уникального идентификатора, хранящегося в хэше:
function HashChanged() {
$get("content").innerHTML = window.location.hash;
}
Хранилище DOM
В настоящий момент, если необходимо сохранить данные на клиенте, единственный стандартизированный и давно уже привычный способ сделать это – использовать document.cookie. Но этому методу не хватает широты и гибкости современных сетевых приложений. Один из наиболее значительных недостатков файлов cookie – ограничение по размеру в 4 КБ. У Internet Explorer 8 есть решение этой проблемы – хранилище DOM.
Хранилище DOM является частью рабочего проекта HTML 5 и предоставляет огромное (около 10 МБ) хранилище данных на стороне клиента. Это хранилище может быть настолько больше отчасти потому, что данные не отправляются на сервер с каждым запросом, как в случае файлов cookie. Вдобавок срок действия localStorage никогда не истекает.
Чтобы сохранить данные и извлечь их из хранилища DOM, нужна лишь пара ключ/значение. Класс JavaScript localStorage предоставляет методы setItem, getItem и removeItem для доступа ко всем возможностям хранилища DOM:
function Save() {
localStorage.setItem("MyItem", $get("Text1").value);
}
function Load() {
$get("Text1").value = localStorage.getItem("MyItem");
}
Данный код производит аналог операций установки и получения значения свойства в C# или Visual Basic, используя хранилище DOM Storage как резервное хранилище. В первую очередь, функция Save сохраняет значение TextBox в хранилище DOM с именем ключа MyItem. Затем функция Load извлекает данные из хранилища DOM Storage, предоставляя то же имя ключа.
Автономный и сетевой режимы работы
Подобно многим веб-разработчикам, я давно мечтал о том дне, когда смогу проверять, есть ли у текущего пользователя работоспособное подключение к Интернету, и в зависимости от этого предоставлять соответствующий набор функций. Теперь Internet Explorer 8 предоставляет состояние подключения к Интернету компьютера, на котором он установлен, с помощью свойства onLine в window.navigator. Если в прошлом это свойство указывало на то, выбрал ли пользователь автономную работу, сейчас оно демонстрирует наличие у текущего пользователя установленного подключения к сети.
В дополнение к свойству onLine, у Internet Explorer 8 теперь имеется два обработчика обратных вызовов – ononline и onoffline (см. «событие ononline» и «событие onoffline»). Обработчик onoffline вызывается, когда система теряет подключение к сети, а ononline – когда подключение восстанавливается. К ним можно присоединить приемники событий и мгновенно получать уведомления о состоянии подключения, что позволяет предоставлять пользователям смешанное обслуживание как при автономной работе, так и при работе в сети.
На рис. 11 показано использование событий ononline и onoffline, определенное в теле веб-страницы. Каждый раз, когда пользователь подключается к сети, запускается метод JavaScript Online. Аналогично, каждый раз, как пользователь отключается, запускается метод Offline.
Рис. 11. Использование событий Ononline и Onoffline
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script type="text/javascript" language="javascript">
function Online() {
alert("I'm online");
}
function Offline() {
alert("I'm offline");
}
</script>
</head>
<body ononline="Online();" onoffline="Offline();">
<form id="form1" runat="server">
</form>
</body>
</html>
Тайм-ауты XMLHttpRequest
У нового XMLHttpRequest в Internet Explorer 8 имеются свойство времени ожидания TimeOut и событие его окончания ontimeout. Это позволяет определить закончившиеся таймаутом запросы XMLHttpRequests и таким образом позволить другим запросам продвинуться вперед в очереди запросов. В нижеприведенном коде я создаю XmlHttpRequest и устанавливаю свойство timeout, а также обработчик события ontimeout:
function GetAReqeust() {
var MyRequest = XMLHttpRequest();
MyRequest.ontmeout = TimeOutHere;
MyRequest.open("GET","https://www.contoso.com/data.xml");
MyRequest.timeout = 2000;
MyRequest.send(null);
}
function TimeOutHere() {
alert("Request to Contoso timed out!");
}
При определении параметров времени ожидания следует придерживаться двух правил: обработчик события истечения времени ожидания должен быть привязан до открытия запроса, а свойство времени ожидания должно быть установлено после открытия запроса.
Одной из серьезных проблем, с которыми можно столкнуться при разработке приложений AJAX, является связь со службами в различных удаленных доменах, благодаря политике единого происхождения.
Существуют способы обхода этой проблемы, но ни один из них не предоставляет того, что нужно: прямого и безопасного метода связи. Internet Explorer 8 предоставляет новый клиентский объект, именуемый XDomainRequest, который позволяет разработчикам получать доступ к удаленным доменам без применения серверного прокси.
Если удаленный сервер предоставляет заголовок Http, именуемый Access-Control-Allow-Origin:*, то все остальные удаленные сайты получат возможность запрашивать данные с текущей веб-страницы. Объект XDomainRequest используется на стороне клиента точно так же, как обычный XmlHttpRequest.
Как можно увидеть, Internet Explorer 8 предлагает ряд компонентов и возможностей, которые разрешают многие из проблем, давно требующих решения. Идет ли речь о более глубокой интеграции содержимого и служб в браузер или использовании новых служб платформы браузера для более удобного обслуживания пользователей, Internet Explorer 8 предоставляет средства для более разнообразного и избавленного от ошибок обслуживания.
Дарон Йондем (Daron Yöndem) — основатель компании Deveload Software, располагающейся в Турции. Он является директором регионального представительства Майкрософт и обладателем звания MVP по ASP.NET. Дарон выступает с лекциями за рубежом, возглавляя ближневосточно-африканский отдел лекций INETA MEA и написал две книги по ASP.NET AJAX.