MSDN Magazine > Home > All Issues > 2008 > May >  À la pointe: Interface à page unique ...
À la pointe
Interface à page unique et motifs AJAX
Dino Esposito

Téléchargement du code disponible sur: CuttingEdge2008_05.exe (203 KB)
Browse the Code Online
Par comparaison au paradigme de développement avec lequel la vaste majorité des applications Web d'aujourd'hui ont été créées, AJAX représente un changement de paradigme pour les architectes de solutions Web. Il s'appuie sur quelques nouveaux principes et règles pour expliquer le comportement d'un système basé sur le Web et nécessite de nouveaux algorithmes pour les mettre en œuvre.
Le principe essentiel sur lequel repose AJAX est l'envoi de données brutes au serveur Web et la réception d'autres données brutes.
Le deuxième principe d'AJAX est que vous orchestrez des opérations vous-même, en contournant ainsi le navigateur hôte et sa mécanique de requête/réponse de page unique.
Le troisième principe d'AJAX est que le code du client est entièrement responsable de la mise à jour de l'interface utilisateur à l'aide des données brutes qu'il reçoit du serveur.
Cet article aidera les développeurs qui souhaitent s'éloigner complètement de la mise en œuvre de défense d'AJAX grâce au rendu partiel. Le rendu partiel est une méthode permettant de disposer de fonctionnalité AJAX tout en restant toujours enraciné dans une architecture Web Forms. Le paradigme d'AJAX est basé sur de nouveaux principes qui nécessitent de nouveaux motifs de conception.

Impact du paradigme d'AJAX
Le rendu partiel d'ASP.NET est un ajout astucieux qui s'appuie sur le modèle publication des formulaires Web classiques. En gros, une page utilisant le rendu partiel possède la même architecture publication et le même cycle de vie de page que ce qui se produit dans une page non AJAX (voir figure 1). La différence, dans ce cas, réside alors dans un intercepteur côté client qui empêche simplement l'action par défaut du navigateur, la soumission de formulaire et la remplace par une requête HTTP de XMLHttpRequest (voir figure 2). Cette astuce évite à l'utilisateur une actualisation de page complète tout en économisant aux développeurs des heures de formation à une nouvelle architecture et de nouveaux motifs.
Figure 1 Opération de publication pleine page traditionnelle (Cliquer sur l'image pour l'agrandir)
Figure 2 Rendu partiel XMLHttpRequest AJAX (Cliquer sur l'image pour l'agrandir)
Il va sans dire que le rendu partiel offre des avantages graphiques dans le contexte de la page courante. Si votre application est conçue autour d'une collection de pages individuelles, cependant, la transition d'une page à la suivante nécessite toujours un chargement de page complète. Le rendu partiel est excellent pour remplacer les publications au sein d'une page, comme la pagination d'une grille, en ajustant l'interface utilisateur après une modification de sélection, ou la modification d'un enregistrement sur place.
Comme le rendu partiel est juste une forme plus intelligente de publication de page, il possède les mêmes restrictions d'architecture que le modèle de formulaires Web. Par exemple, vous ne pouvez avoir qu'une seule requête en attente par fenêtre de navigateur. Avec le modèle actuel pour applications Web (soumettre un formulaire, obtenir une nouvelle page), cette restriction peut ne pas être un problème.
Cependant, une fois que vous élargissez votre horizon avec AJAX, il devient normal de s'attendre à ce qu'un utilisateur exécute plusieurs activités simultanément. Avec le rendu partiel seul, il est impossible pour un utilisateur d'exécuter et de terminer simultanément deux opérations asynchrones.
Le rendu partiel est limité à une opération de requête à la fois afin de conserver la cohérence de l'état d'affichage, qui demeure un élément à part entière du modèle. Et ceci va à l'encontre de la première lettre d'AJAX : asynchrone. Avec le rendu partiel, les publications hors bande JavaScript sont possibles, mais seulement une à la fois. Si une deuxième opération est déclenchée avant que la précédente soit terminée, l'opération en attente est abandonnée pour que la nouvelle opération puisse s'exécuter. Ce principe du dernier arrivé peut être changé par programmation en un principe du premier arrivé dans lequel l'opération en cours est conservée active et la nouvelle est avalée par le système, mais une seule opération est possible à la fois.

Modèle d'interface de page unique
Pour tirer entièrement parti d'AJAX, toutes vos fonctionnalités, ou tout du moins la plupart, doivent se trouver sur une page unique. Ceci porte le nom de modèle SPI (Single Page Interface, interface à page unique). Dans le modèle SPI, toutes les interactions de navigateur avec une application Web ont lieu dans les limites d'une seule page. Cette approche est révolutionnaire pour le Web, mais ce n'est en aucun cas une nouveauté pour Windows® et le développement bureautique. En fin de compte, le modèle SPI est équivalent à une application Windows avec une fenêtre principale (et unique).
Dans le modèle SPI, la page principale est une combinaison d'éléments visuels qui peuvent être chargés, mis à jour et remplacés de manière indépendante (voir figure 3). Ainsi, la page entière ne nécessite pas d'être rechargée à la suite d'une action de l'utilisateur. À tout moment, seuls le contenu et les éléments visuels pertinents à l'étape actuelle de l'application sont affichés. Tout le reste est masqué et sera affiché dès que cela sera nécessaire pour le flux de l'application.
Figure 3 Éléments d'interface de page unique dans une page (Cliquer sur l'image pour l'agrandir)
Le modèle SPI permet naturellement plusieurs fonctionnalités hautement interactives, qui incluent la modification sur place, une interface utilisateur contextuelle, des invites de commentaires d'utilisateur immédiates et des opérations asynchrones. Mais outre les performances et la réceptivité, l'avantage principal du modèle SPI est l'amélioration significative qu'elle offre en termes de convivialité.
Même avec ces nombreux avantages, cependant, vous devez savoir que la conception d'une nouvelle application avec le modèle SPI à l'esprit est un défi, car il n'existe aucun ensemble de motifs et de méthodes recommandées en place. Au final, il existe une manière facile d'utiliser AJAX qui correspond à un grand nombre d'entreprises et de situations. Il existe en outre une méthode pas si facile d'utiliser AJAX et qui commence également à être populaire.
Pour générer des applications AJAX pures, une bonne bibliothèque de widgets d'interface utilisateur est nécessaire pour fournir des effets et des comportements spéciaux. Vous avez besoin d'un modèle d'objet de document (document object model, DOM) riche et personnalisable et utilisant un DOM standard du consortium World Wide Web (W3C) comme moteur sous-jacent mais vous permet de définir votre propre modèle spécifique à l'application. Pour terminer, vous avez besoin d'une infrastructure client et serveur pour développer une interface utilisateur et des scripts codebehind facilement et efficacement. Dans l'idéal, vous disposez également d'outils pour déboguer et tester tout ceci.
Microsoft et les autres fournisseurs fournissent certains de ces éléments. Vous pouvez choisir parmi plusieurs bibliothèques de widgets d'interface utilisateur et il existe également des fournisseurs de contrôles qui définissent leurs propres modèles objet côté client. Ce qui serait vraiment utile serait une infrastructure AJAX améliorée conçue spécifiquement comme alternative aux formulaires Web et inspirée par le modèle SPI.
L'infrastructure MVC (Model View Controller) est un modèle de programmation alternatif, disponible dans la bibliothèque d'extensions d'ASP.NET 3.5. Dans sa forme actuelle, cependant, elle n'a pas non plus grand chose en commun avec AJAX et bien qu'elle n'empêche pas la mise en œuvre des fonctionnalités d'AJAX, elle ne semble pas avoir été conçue pour évoluer vers un modèle SPI. Seul le temps pourra cependant le confirmer.
Dans le modèle SPI, la page principale pointe vers des points de terminaison HTTP dans la même application. Il exécute le code distant mais ne recharge pas la page complète. Il met à jour l'interface utilisateur en utilisant des contrôles qui émettent le code HTML et le code de script. Ces contrôles pourraient être suffisamment intelligents pour créer une bonne partie du code JavaScript qu'ils nécessitent. Par exemple, imaginez un formulaire utilisé pour réserver un vol, avec deux paramètres possibles pour la recherche : l'heure ou le coût. Si l'utilisateur est davantage intéressé par le vol le moins coûteux, vous n'avez pas besoin d'afficher la liste déroulante des horaires. Si l'utilisateur doit décoller à une heure précise, vous devez exécuter le code HTML qui affiche les horaires.
Clairement, cette astuce d'affichage/masquage peut être facilement accomplie avec un peu de code JavaScript. Aujourd'hui, cependant, le développeur de page est responsable de l'écriture de ce code. Les contrôles tels que le contrôle CollapsiblePanel de la boîte à outils de contrôles d'AJAX ASP.NET (asp.net/AJAX/AjaxControlToolkit/Samples/CollapsiblePanel/CollapsiblePanel.aspx) peut également aider à accomplir ceci.

Inconvénients du modèle d'interface de page unique
Bien qu'il permette une expérience utilisateur plus interactive, le modèle SPI, et le paradigme AJAX complet qu'il représente, créent plusieurs problèmes en termes de possibilité de recherche, de gestion d'historique, d'accessibilité et de prise en charge hors connexion. Pendant des années, le suivi des pages Web a été effectué avec des liens permanents. Les moteurs de recherche ont développé leurs activités en faisant correspondre un ensemble de mots clés à une ou plusieurs URL. Ce modèle a fonctionné sur la supposition que chaque état d'une application Web correspond à une page et une URL distinctes.
Avec le modèle SPI dans AJAX, cette supposition n'est plus valide. Si tout (ou presque tout) se produit dans la même page, il n'existe pas de transition d'URL pour indiquer un état et un contenu de site différents. Par conséquent, il n'existe aucune méthode facile d'associer le contenu (et les mots clés) à des URL uniques. Cet aspect du modèle SPI affecte les possibilités de recherche ainsi que la gestion de l'historique (comme la capacité d'utiliser les boutons Précédent et Suivant).
L'historique de navigateur peut en fin de compte devenir un concept démodé, solidement lié au modèle Web classique, statique. Néanmoins, vous devez garder à l'esprit que les utilisateurs sont tellement habitués à ces boutons que les désactiver simplement ne constitue pas une option viable.
L'accessibilité est un autre gros problème avec les applications AJAX. Les lecteurs d'écran les plus répandus ont de grandes difficultés avec le contenu créé par les scripts DOM. En raison de leur conception, toutes les formes d'AJAX (y compris le rendu partiel) sont fortement basées sur les scripts DOM. Par conséquent, vous devrez répondre aux problèmes d'accessibilité par d'autres moyens.
La section 508 du document sur les recommandations d'accessibilité de contenu Web (Web Content Accessibility Guidelines, WCAG) recommande que les pages fournissent un texte fonctionnel alternatif pouvant être lu par les technologies d'assistance lorsqu'elles utilisent des langages d'écriture de script pour afficher le contenu ou créer des éléments visuels. La balise <noscript> a pour objectif la conformité à cette recommandation. Actuellement, la majorité des infrastructures AJAX effectuent leurs mises à jour dynamiques dans la page sans mettre à jour les informations statiques contenues dans les balises <noscript>.

Accessible Rich Internet Applications (ARIA)
Le problème semble être double et impliquer les applications AJAX comme la technologie sur laquelle s'appuient les lecteurs d'écran. D'une part, certains lecteurs d'écran comprennent certains événements de client tels que onclick, keypress et readystatechange. La conscience de ces événements dans un lecteur d'écran pourrait être suffisante pour ajouter au moins une première couche d'accessibilité à plusieurs applications basées sur AJAX.
D'autre part, les lecteurs d'écran ne communiquent habituellement pas de nouvelles informations s'ils ont continué au-delà de l'événement de chargement de page initial dans le DOM. Mais il existe certaines astuces que vous pouvez utiliser pour indiquer au lecteur d'écran que quelque chose a changé. L'une des méthodes les plus efficaces implique la définition du paramètre tabindex sur -1 pour la racine de l'arborescence du DOM mise à jour. Il s'agit cependant d'une astuce et l'accessibilité mérite une solution AJAX plus large.
La nouvelle norme développée par le W3C, appelée Accessible Rich Internet Applications (ARIA), est une solution possible, consistant principalement en des extensions spécifiques au lecteur des balises HTML. Quelques bibliothèques populaires pour AJAX côté client prennent déjà en charge certaines fonctionnalités d'ARIA. Plus généralement, cependant, le problème ne se limite pas seulement à la disponibilité d'une norme conforme à AJAX pour l'accessibilité. Le problème a également, voire particulièrement, trait aux contenus (balises comme script) qu'émettent les contrôles du serveur.
Qu'en est-il des applications hors connexion ? De nombreux développeurs pensent que les applications AJAX autonomes ne sont pas possibles car les applications AJAX sont toujours strictement basées sur Internet. Cette opinion est à mon avis un peu trop simpliste, mais ce n'est pas entièrement faux. De nos jours, presque toutes les applications Web (AJAX et non AJAX) sont des applications basées sur Internet ou un intranet.
Mais les applications non AJAX sont tout à fait capables de travailler hors connexion. Dans le cas de la gestion d'historique, par exemple, l'astuce d'activation de la navigation hors connexion réside entièrement dans le navigateur. Dans une application Web classique, chaque requête HTTP est gérée par le navigateur. Lorsque aucune connexion n'est disponible (et avant de déclencher une erreur HTTP 404), le navigateur examine son cache de pages local.
Une application AJAX diffère d'une application Web classique car elle utilise l'objet XMLHttpRequest au lieu du moteur du navigateur pour envoyer des requêtes HTTP. Pour que les applications AJAX puissent prendre en charge des scénarios hors connexion, vous devez seulement doter l'objet XMLHttpRequest de l'accès au cache du navigateur ou de la capacité de créer et de gérer son propre cache de pages visitées. Certaines infrastructures AJAX commencent à inclure cette capacité. Ce n'est pas une opération simple, cependant, car elle implique l'accès au disque à partir du code JavaScript.

Présentation rapide des motifs AJAX
La prochaine évolution des applications Web mène directement à AJAX et, plus généralement, aux applications Internet riches (Rich Internet Applications, RIA). Trois catégories principales d'applications sont à l'avancée initiale de cette prochaine évolution : les sites classiques basés sur HTML, des applications Web hydrides créés pour intégrer des systèmes multiples dans un serveur frontal unique et basé sur le Web, ainsi que des clients lourds.
Pour la première catégorie, le chargement d'interface utilisateur partiel (rendu partiel) représente la manière facile d'implémenter AJAX avec un impact limité sur le code et les compétences existants.
Le concept d'application Web hydride, d'un autre côté, ne se prête pas nécessairement lui-même à AJAX et à une interaction utilisateur améliorée. Il constitue simplement une façon de recueillir des données d'un assortiment de sources et de les réunir dans une interface utilisateur cohérente. Ceci peut également se produire dans un scénario classique de serveur à serveur. Cependant, AJAX effectue ceci plus simplement et, franchement, de manière plus impressionnante. Du point de vue d'AJAX, une application Web hydride nécessite des formats de sérialisation de données standard (syndication), une infrastructure légère pour l'appel de services via un script, un DOM pouvant être mis à jour et peut-être quelques contrôles visuels riches avec un modèle de programmation pratique.
La création de clients lourds avec AJAX est le plus grand défi. Un client lourd peut être la partie frontale d'un système d'entreprise distribué ou encore la couche de présentation d'une application métier. Il peut également être une application autonome que le service informatique a décidé d'exposer comme application Web. Ces applications, qu'elles soient publiées sur Internet ou limitées à un intranet, nécessitent la richesse et la vitesse d'une interface utilisateur de bureau ordinaire.
Par comparaison au développement Windows, le Web est en retard sur le plan de l'interactivité et de la réactivité. Avec AJAX, vous disposez enfin des outils (et des conditions liées à l'environnement) pour l'évolution vers un modèle substantiellement différent. Mais il nécessite un compromis. D'une part, vous avez des millions d'utilisateurs et développeurs accoutumés à l'ancien Web et à son paradigme d'historique, sa navigation hors connexion, ses favoris, ses opérations uniques, ses transitions de pages et ses liens permanents. D'autre part, vous avez AJAX et son paradigme d'opérations simultanées et d'interface utilisateur unique à mise à jour automatique. Dans ce cas, pour les tâches utilisateur, le modèle AJAX nécessite un véritable modèle d'annulation par opposition à l'utilisation des fonctionnalités d'historique du navigateur et de navigation de page.
Pour écrire le code en conformité avec le modèle SPI, un nouvel ensemble de motifs de conception est nécessaire. La figure 4 répertorie certains motifs AJAX les plus populaires. Comme vous pouvez le voir, la plupart d'entre eux portent principalement sur les techniques et dispositions d'interface utilisateur, bien qu'il soit nécessaire de noter que la liste n'inclut pas certains motifs AJAX populaires et pratiques déjà implémentés dans le la bibliothèque du client AJAX Microsoft®. Par exemple, aucun stub AJAX, modèle JavaScript multinavigateurs ou modèle de suivi d'appel n'est nécessaire si vous utilisez AJAX ASP.NET : toutes ces fonctionnalités sont disponibles par défaut.

Motif Objectif
Browser-Side Templating (Création de modèle côté navigateur) Le motif suggère l'utilisation de modèles HTML qui seront étoffés dynamiquement avec les données récupérées des points de terminaison HTTP distants. Au lieu de régénérer la disposition HTML pour les données immédiatement et en fonction des requêtes, le motif suggère que vous configuriez votre propre couche de modèle. Ce motif représente une alternative au motif HTML Message.
Cross-Domain Proxy (Proxy multidomaines) Ce motif fonctionne sur une connexion serveur à serveur à un service contactable et exposé publiquement et renvoie des données au client. Pour le navigateur client, une application AJAX n'est pas autorisée à se connecter à une URL externe au domaine de la page. Cependant, un proxy local situé dans le même domaine peut facilement s'emparer des données depuis tout emplacement et les renvoyer à l'appelant.
Heartbeat (pulsation) Comme la plupart des applications AJAX peuvent effectuer une grande quantité de travail sur le client sans jamais publier, il est possible que vous deviez informer le serveur qu'un client donné est toujours actif. Le motif suggère que l'application cliente télécharge périodiquement un message de « pulsation » pour indiquer que l'application est toujours chargée et en cours de fonctionnement dans le navigateur.
HTML Message (Message HTML) Les points de terminaison HTTP distants renvoient normalement des données JSON (JavaScript Object Notation) sur le client à intégrer dans le DOM existant. Cette tâche peut uniquement être accomplie via JavaScript. Cependant, si le code client est particulièrement complexe, ou pour des raisons de performances, vous pourriez vouloir renvoyer le code HTML (données et disposition) depuis le serveur, au lieu de données brutes.
Microlink (Microlien) AJAX est principalement utilisé pour effectuer un grand nombre d'activités sur une même page. Comment référencer des contenus externes, à savoir les contenus qui seraient situés sur une page différente dans une application Web classique ? Vous aurez besoin d'une sorte de lien hypertexte au sein de la même page ou « microlink ». Un microlink est une référence à un gros bloc de balises qui est récupéré via des appels au serveur et inséré ensuite dans la page. Un microlink peut être un point de terminaison HTTP ou une méthode sur un objet de commande JavaScript.
On-Demand JavaScript (JavaScript sur demande) Ceci est l'équivalent JavaScript du motif populaire de chargement différé souvent utilisé dans une couche d'accès aux données. Le téléchargement de tout le code JavaScript requis pendant l'initialisation d'une page peut avoir un impact en termes de performances et ralentir l'intégralité du processus. En chargeant les fichiers JavaScript en fonction des demandes, vous procurez à vos pages un chargement beaucoup plus rapide sans affecter leur fonctionnalité.
Page Arrangement (Disposition de page) Comme la majorité de l'activité d'une application a lieu dans la même page, vous devez mettre à jour le contenu de la page et présenter de nouvelles informations lorsque le contexte change. Ce motif suggère simplement que vous utilisiez le DOM pour ajouter/supprimer ou masquer/afficher des éléments pour refléter des transitions d'état.
Periodic Refresh (Actualisation périodique) Le navigateur planifie périodiquement une requête pour obtenir des informations nouvelles ou mises à jour afin d'actualiser l'interface utilisateur.
Popup (Fenêtre indépendante) Ce motif représente la version Web des boîtes de dialogue indépendantes/non indépendantes de Windows. Un popup consiste en un contenu HTML affiché devant le contenu existant pendant une période relativement courte ou jusqu'à ce que l'utilisateur le congédie.
Predictive Fetch (Extraction à l'avance) Ce motif suggère la prévision des actions les plus probables de l'utilisateur et l'extraction à l'avance des données requises. La mise en œuvre de ce motif à des conséquences : il constitue en fin de compte une supposition et elle peut être fausse. Bien qu'efficace pour accroître les performances perçues, ce motif peut également avoir pour résultat une réduction des performances s'il est mal implémenté ou implémenté dans un scénario loin d'être idéal en raison d'une consommation importante de bande passante de serveur.
Progress Indicator (Indicateur de progression) Ce motif est utilisé pour surveiller la progression d'opérations de serveur. Son principe est que l'opération de serveur écrit sa propre progression dans un emplacement partagé qu'un service de surveillance côté client peut lire dans le contexte d'une actualisation de la progression.
Submission Throttling (Limitation de la soumission) L'un des inconvénients potentiels d'AJAX est qu'un nombre trop important de requêtes peut être créé pour le serveur durant une période horaire. Si c'est le cas, il existe un problème évident d'évolutivité. Ce motif suggère que vous utilisiez un minuteur pour télécharger périodiquement des données vers le serveur et un cache ou une file d'attente locaux pour accumuler des requêtes.
Timeout (Expiration) En cas d'opérations lourdes dirigées depuis le client telles que la diffusion ou l'actualisation périodique, un problème consiste à s'assurer que chaque client connecté utilise vraiment l'application. Ce motif suggère que vous chronométriez les opérations lourdes et les repreniez seulement si l'utilisateur le nécessite explicitement.
Unique URLs (URL uniques) Ce motif vous permet d'affecter des URL distinctes aux différentes parties de votre application, reflétant généralement des états différents. Ce motif est couramment utilisé pour prendre en charge l'historique dans les applications AJAX.
Virtual Workspace (Espace de travail virtuel) Le serveur doit répondre aux requêtes aussi rapidement que possible, mais il ne peut pas renvoyer nécessairement toutes les données disponibles en raison de la bande passante. Ce motif suggère que vous génériez une interface utilisateur virtuelle qui donne l'impression que toutes les données sont disponibles alors que seule une petite partie de celles-ci est vraiment sur le client. Il est de la responsabilité de l'application de télécharger des données sur demande et de les mettre en cache localement.
Notez également que les motifs répertoriés dans la figure 4, ainsi que les motifs AJAX, sont en général des motifs de référence plutôt que des motifs de conception. Ils indiquent des façons courantes de travailler, mais tous ne correspondent pas à des problèmes de conception.
Dans la figure 4, j'ai présenté brièvement l'essentiel de chaque motif. Pour le reste de cet article, je vais examiner plus en détail certains de ces motifs. Dans des articles futurs, je reviendrai sur d'autres motifs importants afin de décrire leurs points forts et de démontrer certaines mises en œuvre pratiques. (ajaxpatterns.org est un excellent site Web pour en apprendre plus sur les motifs AJAX).

Motif d'URL unique
Les URL forment l'essence du Web. Les utilisateurs enregistrent leurs URL favorites pour future référence, suivent des URL pour de nouvelles expériences en termes de contenu et utilisent des URL pour revenir à un état précédent. Avec AJAX et le modèle SPI, une application peut accomplir plusieurs tâches à partir d'une seule URL. Ceci menace d'invalider un pilier central de l'expérience Web : un état discret d'une application est identifié par une URL distincte.
Les navigateurs créent leurs propres caches d'URL pendant que les utilisateurs naviguent. Mais avec AJAX, de nombreuses opérations ne sont plus effectuées dans le navigateur et ne sont pas mises en cache dans la liste des URL visitées qu'utilisent les menus Précédent et Suivant. D'autre part, les navigateurs clients n'exposent pas de modèle de programmation pour que le code JavaScript ajoute des URL à la liste. Le modèle d'objet de navigateur fournit seulement des méthodes pour naviguer en avant et en arrière dans la liste existante.
Les motifs à URL uniques attribuent une URL unique et expressive à chaque état d'application significatif. Par exemple, si l'utilisateur clique pour modifier une valeur dans une page AJAX, une nouvelle URL devrait être ajoutée au cache de navigateur, même si l'opération est survenue via XMLHttpRequest depuis la même page.
L'URL est modifiée sans recharger la page en utilisant le code JavaScript suivant :
window.location.hash = stateInfo;
L'effet de ce code est l'ajout d'un fragment agrémenté du préfixe #- à l'URL, comme indiqué ici :
http://www.contoso.com/shopping.aspx#edit-1234
En utilisant ce motif, l'URL est modifiée en fait lorsque vous démarrez toute opération AJAX donnée et permet ainsi le suivi des modifications d'état d'application par le navigateur.
Cependant, cela ne se limite pas à la capture de l'URL. Lorsqu'un navigateur est dirigé vers une URL à base de hachage, il charge l'URL principale et recherche ensuite un fragment de page avec le nom du hachage. Dans un contexte AJAX, le nom de hachage ne pointe pas vers un véritable fragment de page mais plutôt vers des informations spécifiques à l'application qui représentent l'état actuel. Par exemple, edit-1234 peut indiquer que vous modifiez un élément dont l'identificateur possède la référence 1234. Le format est entièrement à votre initiative.
S'il ne peut pas trouver le fragment correct, le navigateur ignore simplement le hachage de l'URL. Par conséquent, la page est chargée pour l'utilisateur mais pas nécessairement dans l'état d'application prévu. Une deuxième astuce est nécessaire. Vous devez intercepter l'événement onload de la page, analyser l'URL, extraire le hachage et exécuter tout code JavaScript nécessaire pour mettre la page dans l'état voulu, comme ceci :
window.onload = function() {
    checkAndParseURL();
}
 
checkAndParseURL() {
     var state = window.location.hash;
     restorePage(state);
}
Une approche similaire est implémentée dans la prise en charge d'historique disponible avec les extensions ASP.NET 3.5. Vous en apprendrez davantage sur le sujet à l'adresse quickstarts.asp.net/3-5-extensions/ajax. La solution des extensions ASP.NET 3.5 est entièrement intégrée à l'infrastructure. Vous le verrez sous la forme de nouvelles propriétés et événements ajoutés au contrôle ScriptManager. Mais en fin de compte il s'agit d'une mise en œuvre du motif d'URL uniques.
De plus, il est important de noter que l'astuce basée sur le hachage d'URL ne fonctionne pas dans Internet Explorer® car Internet Explorer ne reconnaît pas les modifications de hachage pour les URL, sauf dans les cadres incorporés. En fait, tous les navigateurs possèdent des particularités différentes pour le contrôle de la navigation fragmentée (voir weblogs.asp.net/bleroy/archive/2007/09/07/how-to-build-a-cross-browser-history-management-system.aspx pour plus d'informations sur ce sujet). La solution des extensions ASP.NET 3.5 s'occupe de cette différence et la qualifie comme une véritable astuce multinavigateurs.

Motif Timeout
L'un des plus grands avantages d'AJAX est la possibilité d'implémenter des mises à jour de page en temps réel. Cependant, les mises à jour en direct, si elles sont employées de manière incorrecte, peuvent représenter un danger sérieux pour l'application. Imaginez un scénario dans lequel l'utilisateur affiche une page en direct qui interroge le serveur à des intervalles de quelques secondes pour mettre à jour certains contenus. Supposez que l'utilisateur parte pendant plusieurs heures sans arrêter le navigateur. Le résultat est que la page continue l'envoi de requêtes en produisant une charge significative et inutile pour le serveur.
Comment pouvez-vous déterminer si une session client a atteint un délai d'expiration ? Sur le serveur, il existe une expiration de session (timeout), mais dans AJAX la session client a également de l'importance. Pour détecter la fin d'une session client, vous devez vérifier si une activité utilisateur s'est produite, telle que le clic et la frappe pendant une certaine durée. La surveillance de l'activité du clavier et de la souris peut être lourde. Une approche plus simple et plus légère basée sur des minuteurs est généralement plus efficace.
Pour détecter la fin d'une session avec un minuteur, configurez un minuteur client qui expire après un nombre de secondes spécifié (ou, plus probablement de minutes), arrête la tâche en cours et affiche une boîte de dialogue d'alerte. Si l'utilisateur répond à l'invite, le traitement reprend comme à l'accoutumée.
La figure 5 montre un morceau de code JavaScript qui illustre l'essentiel du motif Timeout. La page d'exemple intègre une horloge. L'horloge est obtenue en utilisant un contrôle Label dans un UpdatePanel mis à jour périodiquement par un contrôle Timer, comme ceci :
<script type="text/javascript">
    var timer = null;
    function pageLoad()
    {
        if (timer === null)
        {
            timer = new Samples.TaskTimer(5000, stopTask);
            timer.start();
        }
    }

    function pageUnload()
    {
        if (timer != null)
            timer.stop();
    }

    
    function stopTask()
    {
        // Stop the clock 
        var clock = $find("<%= Timer1.ClientID%>");
        clock._stopTimer();
        
        AskIfTheUserWantsToContinue();
    }
    
    function AskIfTheUserWantsToContinue()
    {
        // Ask if the user wants to continue
        var answer = window.confirm(
          "Is it OK to continue with the clock?");
        if (answer)
        {
            // Restart the task  
            var clock = $find("<%= Timer1.ClientID%>");
            clock._startTimer();
            
            // Restart our own timeout engine
            if (timer !== null)
                timer.start();
            return;
        }        
    }
</script>

protected void Timer1_Tick(object sender, EventArgs e)
{
    Label1.Text = DateTime.Now.ToLongTimeString();
}
L'horloge est une tâche lourde qui pourrait inonder le serveur de requêtes. L'idée consiste à configurer un minuteur qui demande périodiquement à l'utilisateur s'il veut continuer à utiliser l'horloge. Le code d'expiration arrête tout d'abord l'horloge puis affiche la boîte de message. En fonction de la réponse de l'utilisateur, l'horloge est redémarrée.
Le code utilise la fonction $find pour trouver un composant AJAX ASP.NET. Dans ce cas précis, il se trouve être le modèle objet client du contrôle de serveur Timer ASP.NET. La figure 6 montre la page avec une fenêtre contextuelle demandant à l'utilisateur s'il veut continuer.
Figure 6 Demander à l'utilisateur s'il veut continuer (Cliquer sur l'image pour l'agrandir)

Veuillez envoyer vos questions et commentaires à l’attention de Dino à l’adresse suivante : cutting@microsoft.com.


Dino Esposito est l'auteur de Programming ASP.NET 3.5 Core References. Basé en Italie, Dino participe régulièrement aux différentes manifestations du secteur organisées aux quatre coins du monde. Vous trouverez son blog à l'adresse : weblogs.asp.net/despos.

Page view tracker