Exemple de travail

Prenons l'exemple d'un site Web de trois pages utilisant AJAX pour les charger sans recharger la totalité de la page affichée (habillage et navigation sont conservés).

La navigation pourrait ressembler à ceci:

 
Sélectionnez

<ul id='nav'>
	<li><a href="javascript:load('page1.html')">Page 1</a></li>
	<li><a href="javascript:load('page2.html')">Page 2</a></li>
	<li><a href="javascript:load('page3.html')">Page 3</a></li>
</ul>

Dans un site Web traditionnel, la navigation ressemblerait plutôt à ceci :

 
Sélectionnez

<ul id='nav'>
	<li><a href="page1.html">Page 1</a></li>
	<li><a href="page2.html">Page 2</a></li>
	<li><a href="page3.html">Page 3</a></li>
</ul>

Pour palier au problème du référencement, les moteurs de recherche devraient avoir accès à cette deuxième version.

Les deux ne sont pas incompatibles techniquement. Il suffit de produire un code (X)HTML pour les moteurs de recherche et de court-circuiter les liens avec JavaScript pour faire des chargement via AJAX.

 
Sélectionnez

function initNav() {
	var nav = document.getElementById('nav');
	var liens = nav.getElementsByTagName('A');
	for(var i=0;i<liens.length;i++){
		liens[i].onclick = load;
	}
}

La fonction initNav doit être exécutée au chargement de la page, la fonction load doit interrompre le traitement par défaut du clic et nous avons résolu notre premier problème.

Fonctionnement sans JavaScript

Si JavaScript est désactivé, les URLs définies dans le href vont être utilisées quand on clique sur les liens. Le navigateur devra recevoir un contenu de page complet (de même pour les moteurs de recherche).

Dans le cadre d'une application AJAX, les contenus que l'on souhaite charger sont partiels (pas de DOCTYPE, ni de body), juste le contenu, c'est-à-dire des fragments (X)HTML.

Pour pallier ce problème il faut pouvoir produire les deux types de contenu depuis le serveur. Le plus simple étant de séparer les fragments (X)HTML dans des fichiers distincts et de travailler avec un modèle (X)HTML contenant l'habillage du site et sa navigation mais sans contenu.

Exemple de structure du site :

 
Sélectionnez

model.html
fragments/page1.html
fragments/page2.html
fragments/page3.html
index.php

La page model.html pourrait ressembler à ceci :

 
Sélectionnez

<!DOCTYPE ...>
<html ...>
	<head>...</head>
	<body>
		<ul id="nav">
			<li><a href="page1.html">Page 1</a></li>
			<li><a href="page2.html">Page 2</a></li>
			<li><a href="page3.html">Page 3</a></li>
		</ul>
		<div id="contenu'">[[CONTENU]]</div>
	</body>
</html>

On peut utiliser PHP pour produire les pages avec un code du genre :

 
Sélectionnez

$page = $_GET['page'];
$fragment = file_get_contents("fragments/$page");
$model = file_get_contents('model.html');
echo str_replace('[[CONTENU]]', $fragment, $model);

Les URL produisant des pages complètes sont de la forme : index.php?page=page1.html, celles permettant d'obtenir des fragments sont ainsi : fragments/page1.html (celles-ci ne seront jamais indexées).

En utilisant l'URL-rewriting, on peut facilement transformer les URL comme page1.html en index.php?page=page1.html.

Ainsi, nous avons une application totalement fonctionnelle sans JavaScript et qui peut être référencée par les moteurs de recherche.

Gestion de l'URL avec AJAX

Pour éviter le rechargement de la page avec AJAX, on ne peut pas se permettre d'en changer l'URL, ce qui rentre en conflit avec ce qui a été dit plus haut et selon la règle qu'à chaque contenu doit correspondre une URL et réciproquement.

Heureusement, il est possible de modifier l'ancre d'une URL sans recharger la page (les ancres servant initialement à se déplacer dans une même page).

On peut modifier l'URL de la barre d'adresse du navigateur en JavaScript sans recharger la page en appliquant une ancre avec document.location.replace('#page1.html'). Ceci doit être fait après chaque requête AJAX qui charge un nouveau contenu.

Les URLs de notre application AJAX ressemblent donc à :

 
Sélectionnez

/#page1.html
/#page2.html
/#page3.html

Il est important que l'application AJAX examine l'URL du navigateur lors du premier chargement de la page de manière à afficher le bon contenu. Ces URLs comportant des ancres peuvent être utilisées suite à la mise en favoris d'une page par exemple.

Conflit lors de l'arrivée sur le site par une page référencée

En accédant à un site par l'URL page2.html, référencée par un moteur de recherche, étant donné l'absence d'ancre, l'application AJAX pourrait traiter ce cas et afficher le contenu de la page2. Cependant, lorsque l'on navigue dans le site sur la page3, on aurait une URL page2.html#page3.html, ce qui n'est pas très cohérent d'une part et qui contredit la règle d'unicité entre le contenu et les URL d'autre part.

L'application AJAX devrait donc faire une redirection en JavaScript vers l'URL /#page2.html au plus tôt, avant l'affichage du corps de la page (en plaçant un script dans l'entête).

Exemple fonctionnel

Voici un petit exemple fonctionnel à placer sur votre serveur (qui doit supporter le .htaccess pour l'URL-rewriting). Télécharger (2.58 ko).

Remerciements

Je tiens à remercier pixelomilcouleurs et dourouc05 pour leur relecture de cet article.

Merci aussi à Didier Mouronval pour l'aide apportée à la publication de cet article.