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 :
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 %25{QUERY_STRING} %5E_escaped_fragment_=(.*)$ [NC]
RewriteRule (.*) http://demo.johanbleuzen.fr:8081/headless-browser/?page=$1&ajax=%251 [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
Revoilà l'ensemble des ressources utilisées dans ce tutoriel:
- Le SRC
- Le WAR
10 Commentaires
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...
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 :)
Rhô la bête !
Bravissimo Johan !
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.
@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 !
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.
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
Hello,
Vraiment du mal à faire fonctionner la chose en suivant les indications ...
Faut il le JDK ou le JEE ?
Apparement il manque quelques choses pour faire fonctionner cela avec un sous-domaine ...
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