J'ai travaillé sur la façon de rendre un SPA crawlable par Google en fonction des instructions de Google . Même s'il existe de nombreuses explications générales, je n'ai trouvé nulle part un didacticiel pas à pas plus complet avec des exemples réels. Après avoir terminé cela, j'aimerais partager ma solution afin que d'autres puissent également l'utiliser et éventuellement l'améliorer davantage.
J'utilise MVC
avec les Webapi
contrôleurs et Phantomjs côté serveur et Durandal côté client avec push-state
activé; J'utilise également Breezejs pour l'interaction de données client-serveur, ce que je recommande vivement, mais je vais essayer de donner une explication suffisamment générale qui aidera également les personnes utilisant d'autres plates-formes.
143
Réponses:
Avant de commencer, assurez-vous de comprendre ce que google exige , en particulier l'utilisation d' URL jolies et laides . Voyons maintenant l'implémentation:
Côté client
Du côté client, vous n'avez qu'une seule page html qui interagit dynamiquement avec le serveur via des appels AJAX. c'est ça le SPA. Toutes les
a
balises côté client sont créées dynamiquement dans mon application, nous verrons plus tard comment rendre ces liens visibles au bot de google sur le serveur. Chacun de cesa
besoins d'étiquette pour être en mesure d'avoir unpretty URL
dans lahref
balise si le bot de Google va explorer. Vous ne voulez pas que lahref
partie soit utilisée lorsque le client clique dessus (même si vous voulez que le serveur puisse l'analyser, nous verrons cela plus tard), car nous ne voulons peut-être pas qu'une nouvelle page se charge, uniquement pour faire un appel AJAX pour obtenir des données à afficher dans une partie de la page et changer l'URL via javascript (par exemple en utilisant HTML5pushstate
ou avecDurandaljs
). Donc, nous avons à la fois unhref
attribut pour google ainsi que suronclick
lequel fait le travail lorsque l'utilisateur clique sur le lien. Maintenant, puisque j'utilisepush-state
je n'en veux pas#
sur l'URL, donc unea
balise typique peut ressembler à ceci:<a href="http://www.xyz.com/#!/category/subCategory/product111" onClick="loadProduct('category','subCategory','product111')>see product111...</a>
«catégorie» et «sous-catégorie» seraient probablement d'autres expressions, telles que «communication» et «téléphones» ou «ordinateurs» et des «ordinateurs portables» pour un magasin d'appareils électriques. De toute évidence, il y aurait de nombreuses catégories et sous-catégories différentes. Comme vous pouvez le voir, le lien est directement vers la catégorie, la sous-catégorie et le produit, et non comme des paramètres supplémentaires vers une page de «magasin» spécifique telle que
http://www.xyz.com/store/category/subCategory/product111
. C'est parce que je préfère des liens plus courts et plus simples. Cela implique qu'il n'y aura pas de catégorie avec le même nom qu'une de mes 'pages', c'est à dire 'Je n'entrerai pas dans la façon de charger les données via AJAX (la
onclick
partie), recherchez-les sur google, il y a beaucoup de bonnes explications. La seule chose importante que je veux mentionner ici est que lorsque l'utilisateur clique sur ce lien, je veux que l'URL du navigateur ressemble à ceci:http://www.xyz.com/category/subCategory/product111
. Et c'est l'URL n'est pas envoyée au serveur! rappelez-vous, c'est un SPA où toute l'interaction entre le client et le serveur se fait via AJAX, pas de liens du tout! toutes les `` pages '' sont implémentées côté client et les différentes URL n'appellent pas le serveur (le serveur a besoin de savoir comment gérer ces URL au cas où elles seraient utilisées comme liens externes d'un autre site vers votre site, nous verrons cela plus tard sur la partie côté serveur). Maintenant, cela est géré à merveille par Durandal. Je le recommande fortement, mais vous pouvez également sauter cette partie si vous préférez d'autres technologies. Si vous le choisissez et que vous utilisez également MS Visual Studio Express 2012 pour le Web comme moi, vous pouvez installer le kit de démarrage Durandal , et là, dansshell.js
, utilisez quelque chose comme ceci:Il y a quelques points importants à noter ici:
route:''
) est pour l'URL qui ne contient pas de données supplémentaires, c'est-à-direhttp://www.xyz.com
. Dans cette page, vous chargez des données générales à l'aide d'AJAX. Il se peut qu'il n'y ait en fait aucunea
balise sur cette page. Vous voulez ajouter la balise suivante si le bot de Google saura quoi faire avec elle:<meta name="fragment" content="!">
. Cette balise permettra au bot de Google de transformer l'URL verswww.xyz.com?_escaped_fragment_=
laquelle nous verrons plus tard.mapUnknownRoutes
qu'intervient. Il mappe ces routes inconnues à la route «magasin» et supprime également tout «! à partir de l'URL au cas où ellepretty URL
serait générée par le moteur de recherche de Google. La route 'store' prend les informations dans la propriété 'fragment' et effectue l'appel AJAX pour obtenir les données, les afficher et modifier l'URL localement. Dans mon application, je ne charge pas une page différente pour chaque appel de ce type; Je ne change que la partie de la page où ces données sont pertinentes et change également l'URL localement.pushState:true
qui indique à Durandal d'utiliser les URL d'état push.C'est tout ce dont nous avons besoin du côté client. Il peut également être implémenté avec des URL hachées (dans Durandal, vous supprimez simplement le
pushState:true
pour cela). La partie la plus complexe (du moins pour moi ...) était la partie serveur:Du côté serveur
J'utilise
MVC 4.5
côté serveur avec desWebAPI
contrôleurs. Le serveur doit en fait gérer 3 types d'URL: celles générées par Google - à la foispretty
etugly
aussi une URL «simple» avec le même format que celle qui apparaît dans le navigateur du client. Voyons comment procéder:Les jolies URL et les «simples» sont d'abord interprétées par le serveur comme s'il essayait de référencer un contrôleur inexistant. Le serveur voit quelque chose comme
http://www.xyz.com/category/subCategory/product111
et recherche un contrôleur nommé «catégorie». Donc, dansweb.config
j'ajoute la ligne suivante pour les rediriger vers un contrôleur de gestion des erreurs spécifique:Maintenant, cela transforme l'URL à quelque chose comme:
http://www.xyz.com/Error?aspxerrorpath=/category/subCategory/product111
. Je veux que l'URL soit envoyée au client qui chargera les données via AJAX, donc l'astuce ici est d'appeler le contrôleur «index» par défaut comme s'il ne faisait référence à aucun contrôleur; Je fais cela en ajoutant un hachage à l'URL avant tous les paramètres «category» et «subCategory»; l'URL hachée ne nécessite aucun contrôleur spécial à l'exception du contrôleur «index» par défaut et les données sont envoyées au client qui supprime ensuite le hachage et utilise les informations après le hachage pour charger les données via AJAX. Voici le code du contrôleur du gestionnaire d'erreurs:Mais qu'en est-il des URL laides ? Ceux-ci sont créés par le bot de Google et doivent renvoyer du HTML brut contenant toutes les données que l'utilisateur voit dans le navigateur. Pour cela, j'utilise phantomjs . Phantom est un navigateur sans tête faisant ce que le navigateur fait du côté client - mais du côté serveur. En d'autres termes, phantom sait (entre autres) comment obtenir une page Web via une URL, l'analyser, y compris exécuter tout le code javascript qu'elle contient (ainsi que récupérer des données via des appels AJAX), et vous rendre le HTML qui reflète le DOM. Si vous utilisez MS Visual Studio Express, vous souhaitez souvent installer phantom via ce lien .
Mais d'abord, lorsqu'une URL laide est envoyée au serveur, nous devons l'attraper; Pour cela, j'ai ajouté au dossier 'App_start' le fichier suivant:
Ceci est appelé depuis 'filterConfig.cs' également dans 'App_start':
Comme vous pouvez le voir, 'AjaxCrawlableAttribute' achemine les URL laides vers un contrôleur nommé 'HtmlSnapshot', et voici ce contrôleur:
L'associé
view
est très simple, juste une ligne de code:@Html.Raw( ViewBag.result )
Comme vous pouvez le voir dans le contrôleur, phantom charge un fichier javascript nommé
createSnapshot.js
sous un dossier que j'ai créé appeléseo
. Voici ce fichier javascript:Je tiens d'abord à remercier Thomas Davis pour la page où j'ai obtenu le code de base :-).
Vous remarquerez quelque chose d'étrange ici: phantom continue de recharger la page jusqu'à ce que la
checkLoaded()
fonction retourne true. Pourquoi donc? c'est parce que mon SPA spécifique fait plusieurs appels AJAX pour obtenir toutes les données et les placer dans le DOM sur ma page, et phantom ne peut pas savoir quand tous les appels sont terminés avant de me renvoyer le reflet HTML du DOM. Ce que j'ai fait ici, c'est après le dernier appel AJAX, j'ajoute un<span id='compositionComplete'></span>
, de sorte que si cette balise existe, je sache que le DOM est terminé. Je fais cela en réponse à l'compositionComplete
événement de Durandal , voir icipour plus. Si cela ne se produit pas dans les 10 secondes, j'abandonne (cela ne devrait prendre qu'une seconde au maximum). Le HTML renvoyé contient tous les liens que l'utilisateur voit dans le navigateur. Le script ne fonctionnera pas correctement car les<script>
balises qui existent dans l'instantané HTML ne référencent pas la bonne URL. Cela peut également être modifié dans le fichier fantôme javascript, mais je ne pense pas que ce soit nécessaire car le snapshort HTML est uniquement utilisé par Google pour obtenir lesa
liens et non pour exécuter javascript; ces liens font référence à une jolie URL, et si en fait, si vous essayez de voir l'instantané HTML dans un navigateur, vous obtiendrez des erreurs javascript mais tous les liens fonctionneront correctement et vous dirigeront à nouveau vers le serveur avec une jolie URL cette fois obtenir la page entièrement fonctionnelle.Ça y est. Maintenant, le serveur sait comment gérer à la fois les URL jolies et laides, avec l'état push activé sur le serveur et le client. Toutes les URL laides sont traitées de la même manière en utilisant un fantôme, il n'est donc pas nécessaire de créer un contrôleur distinct pour chaque type d'appel.
Une chose que vous pourriez préférer le changement est de ne pas faire une « catégorie / sous / produit » appel général , mais d'ajouter un « magasin » de sorte que le lien ressemblera à quelque chose comme:
http://www.xyz.com/store/category/subCategory/product111
. Cela évitera le problème dans ma solution que toutes les URL invalides sont traitées comme si elles étaient en fait des appels au contrôleur `` index '', et je suppose que celles-ci peuvent être traitées ensuite dans le contrôleur `` magasin '' sans l'ajout de celui queweb.config
j'ai montré ci-dessus .la source
Google est maintenant en mesure de rendre les pages SPA: abandon de notre schéma d'exploration AJAX
la source
Voici un lien vers un enregistrement screencast de mon cours de formation Ember.js que j'ai organisé à Londres le 14 août. Il décrit une stratégie pour votre application côté client et pour votre application côté serveur, ainsi qu'une démonstration en direct de la façon dont la mise en œuvre de ces fonctionnalités fournira à votre application JavaScript à page unique une dégradation gracieuse même pour les utilisateurs avec JavaScript désactivé. .
Il utilise PhantomJS pour faciliter l'exploration de votre site Web.
En bref, les étapes requises sont:
Une fois cette étape terminée, il appartient à votre backend de diffuser la version statique de votre HTML dans le cadre de la balise noscript sur cette page. Cela permettra à Google et aux autres moteurs de recherche d'explorer chaque page de votre site Web, même si votre application est à l'origine une application à page unique.
Lien vers le screencast avec tous les détails:
http://www.devcasts.io/p/spas-phantomjs-and-seo/#
la source
Vous pouvez utiliser ou créer votre propre service pour prerender votre SPA avec le service appelé prerender. Vous pouvez le vérifier sur son site Web prerender.io et sur son projet github (il utilise PhantomJS et il rend votre site Web pour vous).
C'est très facile de commencer. Il vous suffit de rediriger les requêtes des robots d'exploration vers le service et ils recevront le HTML rendu.
la source
Vous pouvez utiliser http://sparender.com/ qui permet d'explorer correctement les applications à page unique.
la source