Le référencement de l’Ajax avec un Headless Browser

Publié le 7 juillet 2011 Optimisation technique SEO
Johan Bleuzen
Ajax et SEO

Comment peut-on référencer de manière efficace les contenus en Ajax ? La meilleur solution pour le moteur de recherche et pour le visiteur reste l’utilisation d’un HeadLess Browser pour gérer de manière dynamique ces contenus, comme le fait si bien Twitter avec ses urls #!.

Voici comment faire, de A à Z :

Ce tutoriel a été réalisé sur une machine linux avec une JDK « Sun » en version 1.6.14 et un serveur Web Apache en version 2.2 (versions à titre indicatif). L’objectif est de créer un « headless-browser » (navigateur sans tête) qui va générer une page HTML après un appel à une action Ajax. Du coup, je suppose que vous disposez déjà d’une webapp avec une action Ajax pour réaliser vos tests.

Le code proposé ici, n’est absolument pas prêt pour être utilisé en production, il n’y a pas de gestions d’erreurs, il n’y a pas de gestion de cache, il n’y a aucune optimisation du code. Ce tutoriel est parfait pour réaliser un PoC, rien de plus…

Configuration de Jetty

Jetty est un serveur d’application léger qui permet de rapidement développer et déployer des applications JEE. C’est la solution qui a été retenue pour créer ce navigateur headless.

Installation de Jetty

Il faut donc télécharger une version de Jetty et la dézipper sur son serveur, j’ai choisi une version récente mais on peut utiliser n’importe quelle version du serveur à condition qu’elle supporte le déploiement automatique des war.

# Téléchargement de Jetty
$> wget http://dist.codehaus.org/jetty/jetty-hightide-7.3.1/jetty-hightide-7.3.1.v20110307.tar.gz
# Décompression de l'archive
$> tar -xvf jetty-hightide-7.3.1.v20110307.tar.gz
# Installation dans /opt
$> mv jetty-hightide-7.3.1.v20110307 /opt/jetty

Si vous décidiez de ne pas installer Jetty dans un répertoire « standard » (voir le fichier jetty.sh dans le répertoire bin pour connaitre la liste de ces répertoires), il sera alors nécessaire de définir la variable $JETTY_HOME dans votre shell avant de pouvoir démarrer le serveur.

Pour les utilisateurs de Linux, il est possible d’installer plus rapidement Jetty en faisant un simple apt-get, mais ce n’est pas la solution que j’ai retenu. En théorie cela ne change rien, voici la commande à utiliser  :

$> apt-get install jetty

Port d’écoute de Jetty

Pour fonctionner Jetty a besoin d’écouter sur un port, par défaut il utilise le port 8080, puisqu’en général le port 80 est utilisé par les serveurs HTTP. Libre à vous de modifier ce port si vous avez déjà un service tournant sur le port 8080. Si vous voulez, modifier le port d’écoute de Jetty, il faut éditer le fichier présent dans /opt/jetty/etc/jetty-bio.xml.

Vous devrez également adapter la suite du tutoriel pour cette modification.

Nettoyage de l’installation de Jetty

Cette étape est facultative, mais permet d’alléger l’empreinte de Jetty en mémoire. En effet, par défaut Jetty est fourni avec différentes webapps de tests et/ou de démonstration, il peut être utile de les supprimer. Supprimez tous les fichiers du répertoire /opt/jetty/webapp:

$> rm -rf /opt/jetty/webapps/*

Une fois cette étape terminée, il faut ensuite supprimer tous les fichiers de contextes liés aux webapps que l’on vient de supprimer

$> rm -rf /opt/jetty/contexts/*

L’installation de Jetty et sa configuration est maintenant terminée, passons à la phase d’installation de la webapp.

Mise en place de la webapp

Maintenant que nous avons un serveur d’application configuré, il ne reste plus qu’à déployer notre navigateur sans tête sur notre serveur.

Soit vous récupérez les sources,  vous les compiler et générez votre war à la main, soit vous téléchargez directement le war que vous installez sur votre serveur.

Création de la Web ARchive

La webapp se compose d’une unique servlet qui va faire tout le traitement toute seul, vous pouvez récupérer les sources mais le plus important est le war. Si vous voulez vous faire le war vous même, il suffit d’exécuter les commandes suivantes dans un terminal :

$> cd /tmp

$> wget URL_A_CREER

$> unzip headless-browser-src.zip

$> cd headless-browser

# Execution de Maven pour générer le war

$> mvn compile war:war

$> cd target

# On renomme le war pour supprimer la version

$> mv headless-browser-1.0-SNAPSHOT.war /opt/jetty/webapps/headless-browser.war

Le SRC est ici :

C’est terminé, vous pouvez passé au lancement de Jetty.

Installation de la Web Archive

Si vous avez confiance (et vous avez raison), vous pouvez directement récupérer le war, il faut juste le télécharger et le placer dans le répertoire webapps de votre installation Jetty :

$> cd /opt/jetty/webapps
$> wget URL_A_CREER

Note importante : Le nom que vous allez donner à ce war modifiera l’URL d’accès au « headless browser ». J’ai choisi de nommer le fichier ‘headless-browser.war’, si vous changez le nom du war, il faudra ajuster la suite du tutoriel.

Lancement du serveur Jetty

Au début du tutoriel, je vous ai demandé d’installer une version de Jetty permettant l’auto-déploiement. L’objectif était de simplifier au maximum la mise en place, il suffit de déposer un war dans un répertoire et de lancer le serveur pour que l’application soit automatiquement déployée sans aucune configuration supplémentaire.

Pour démarrer le serveur Jetty, il faut saisir les commandes suivantes:

$> cd /opt/jetty
$> java -jar start.jar

Voici la sortie que vous devriez voir apparaitre dans votre terminal :

$> java -jar start.jar
2011-04-01 06:53:29.385:INFO::jetty-7.3.1.v20110307
2011-04-01 06:53:29.415:INFO::Deployment monitor /opt/jetty/webapps at interval 1
2011-04-01 06:53:29.419:INFO::Deployable added: /opt/jetty/webapps/headless-browser.war
2011-04-01 06:53:29.696:INFO::Extract jar:file:/opt/jetty/webapps/headless-browser.war!/ to /private/var/folders/ot/otntqDV1HVCHTZym2eKj9k+++TI/-Tmp-/jetty-0.0.0.0-8080-headless-browser.war-_headless-browser-any-/webapp
2011-04-01 06:53:32.124:INFO::started o.e.j.w.WebAppContext{/headless-browser,file:/private/var/folders/ot/otntqDV1HVCHTZym2eKj9k+++TI/-Tmp-/jetty-0.0.0.0-8080-headless-browser.war-_headless-browser-any-/webapp/},/opt/jetty/webapps/headless-browser.war
2011-04-01 06:53:32.279:INFO::Deployment monitor /opt/jetty/contexts at interval 1
2011-04-01 06:53:32.338:INFO::Started SelectChannelConnector@0.0.0.0:8080

Les informations importantes de ces logs sont les lignes qui informent que le war a été ajouté et extrait dans un répertoire temporaire. Maintenant le déploiement terminé, vous devriez pouvoir ouvrir votre navigateur et saisir l’URL suivante : localhost:8080/headless-browser/ pour obtenir le résultat suivant :

Jetty en cours de fonctionnement
Jetty en cours de fonctionnement

Si vous ne souhaitez pas voir les logs apparaitre dans la sortie standard, il est possible de démarrer Jetty d’une manière alternative qui redirigera la sortie standard dans un fichier de log :

$> cd /opt/jetty/bin

$> chmod +x jetty.sh

$> ./jetty.sh start

Configuration Apache

Je suppose que si vous lisez cet article, vous avez déjà un serveur Apache fonctionnel, il va falloir faire quelques modifications à la configuration de votre serveur afin de faire communiquer Apache avec le headless-browser que nous venons d’installer.

Cette phase de configuration va donc permettre à Apache de communiquer avec Jetty, pour atteindre cet objectif, on va utiliser le mod_proxy et le mod_rewrite.

Activer les différents mods

Pour activer les différents mods, il n’y a rien de compliquer,  il suffit de saisir les commandes suivantes :

#> a2enmod proxy

#> a2enmod proxy_http

#> a2enmod rewrite

Ne pas oublier de recharger Apache :

#> /etc/init.d/apache2 reload

Configuration du mod_proxy

Cette configuration est très importante, car c’est ce qui va permettre à Apache de transmettre les paramètres à Jetty qui renverra la page généré au client. De plus, le mod_proxy est un outil à manipuler avec précaution, il faut obligatoirement restreindre l’accès sous peine de voir son serveur recevoir une tonne de spammeur qui ne demandent rien pour utiliser votre serveur en tant que proxy.
J’en ai fait l’amère expérience pendant les tests…

Voici donc la configuration du proxy qui se trouve dans le fichier /etc/apache2/mods-available/proxy.conf. Il vous faudra modifier la ligne Allow avec le domaine qui sera utilisé pour votre test, ceci va restreindre les machines qui pourront accéder au proxy.

#turning ProxyRequests on and allowing proxying from all may allow
 #spammers to use your proxy to send email.
 ProxyRequests Off
 AddDefaultCharset off
 Order deny,allow
 Deny from all
 Allow from localhost
 # Enable/disable the handling of HTTP/1.1 "Via:" headers.
 # ("Full" adds the server version; "Block" removes all outgoing Via: headers)
 # Set to one of: Off | On | Full | Block
 ProxyVia Off

Vérifiez que apache démarre toujours après cette étape.

Configuration du mod_rewrite

Généralement le mod_rewrite est un outil qui est quasiment toujours actif lorsque l’on travaille avec Apache. Ce mod va nous permettre de transformer l’URL à base de _escaped_fragment_ utilisée par Google en une URL compréhensible par le headless-browser sur Jetty.

Pour ce faire, il faut créer un fichier .htaccess à la racine de votre site de test si ce n’est pas déjà fait. Editez le fichier pour ajouter la réécriture suivante dans le fichier :

RewriteEngine on
RewriteCond %{QUERY_STRING} ^_escaped_fragment_=(.*)$ [NC]
RewriteRule (.*) http://demo.johanbleuzen.fr:8081/headless-browser/?page=$1&ajax=%1 [QSA,L,P]

Cette réécriture qui est plus compliquée qu’il n’y parait permet de transformer une requête faite par le crawler Google en une URL compréhensible par le headless-browser.

En gros, elle vérifie que l’URL contiennet le terme « _escaped_fragment_=« , si c’est le cas alors c’est une requête effectuée par le crawler et on réécrit l’URL vers le serveur Jetty qui comprend les requêtes avec deux paramètres :

  • $1 : Correspond au document qui est accédé (par exemple index.php)
  • %1 : correspond au fragment récupéré dans la condition (après le signe ‘=’)

Un headLess Browser pour le référencement

Si la configuration d’Apache s’est bien passé, votre navigateur headless est désormais fonctionnel. Pour vérifier, il vous suffit de saisir l’URL suivante dans votre navigateur : localhost/?_escaped_fragment_=VOTRE_ID_AJAX

Headless Browser en fonctionnement
Le Headless Browser en fonctionnement

Revoilà l’ensemble des ressources utilisées dans ce tutoriel:

  • Le SRC
  • Le WAR

Johan Bleuzen

Développeur Web en région parisienne

10 Commentaires

Daniel Roch Le 07 juillet 2011 à 10h05

Un grand bravo à toi Johan pour ce superbe article. Avec ça, je sais maintenant comment installer un HeadLess Browser, car les guidelines de Google sont beaucoup trop vagues à ce sujet…

Johan Le 07 juillet 2011 à 11h12

Merci !
Mais comme on l’avait dit dans l’article présentant les résultats du point de vue SEO, cette technique est à utiliser pour de gros sites et la il y a des améliorations à faire dans le code…

En tout cas ca a été intéressant d’un point de vue technique comme étude :)

Philippe Le 07 juillet 2011 à 15h51

Rhô la bête !
Bravissimo Johan !

Kiwiworkshop Le 07 juillet 2011 à 16h02

Chapeau pour ce tuto. Ca reste quand même une grosse manip, mais travaillant avec de très gros clients, je garde ce tuto sous la main et je l’utiliserai à coup sûr.

Ma seule remarque, est qu’il manquerait éventuellement un explicatif sur ce qu’est un « Headless Browser ». Je pense que pour toi c’est évident, mais ca l’est pas pour tous :D

Merci beaucoup pour ton travail.

Johan Le 08 juillet 2011 à 12h10

@KiwiWorkshop :
Oui ca reste une grosse manip de faire quelque chose qui marche pour beaucoup d’URLs, pour faire du test cela peut convenir aussi…

Pour l’explication du « Headless Browser » c’est une remarque pertinente, je vais voir ce que je peux faire pour expliquer ce que c’est !

Mimie Le 24 octobre 2011 à 14h14

Tuto intéressant, pour ma part j’utilise une Servlet qui va intercepter les urls « escaped_fragment » : http://code.google.com/p/google-web-toolkit/source/browse/branches/crawlability/samples/showcase/src/com/google/gwt/sample/showcase/server/CrawlServlet.java?r=6211.

Cependant l’attente d’exécution du JavaScript (20000) fait que le robot va croire que le site est très lent alors qu’il n’en est rien.
Constatez-vous aussi que l’affichage des pages du crawler s’affichent beaucoup plus lentement que les pages du site lui-même ? pour ma part c’est impressionnant et donc quasi inutilisable.

Johan Le 24 octobre 2011 à 14h49

Bonjour Mimie,
Dans mes tests, le premier affichage était effectivement plus lent (normal, le temps de la compilation du servlet). En revanche une fois le bytecode généré, je n’ai remarqué aucun problème de rapidité d’affichage…

Johan

marmits Le 12 juin 2012 à 10h54

Hello,
Vraiment du mal à faire fonctionner la chose en suivant les indications …
Faut il le JDK ou le JEE ?

marmits Le 13 juin 2012 à 16h47

Apparement il manque quelques choses pour faire fonctionner cela avec un sous-domaine …

Axel Le 20 décembre 2013 à 15h39

Bonjour,
pouvez-vous svp nous communiquer le site auteur du fichier headlessbrowser.war ?
Qui est son auteur ?
On dirait qu’il ne s’agit pas de la version la plus récente.
Merci beaucoup

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *