Les applications à page unique (SPA) sont alimentées par des modèles de rendu côté client, offrant une expérience très dynamique aux utilisateurs finaux. Récemment, Google a annoncé qu'il explorerait les pages Web et exécuterait JavaScript comme les utilisateurs normaux, permettant ainsi aux sites Web alimentés par des frameworks SPA (Angular, Ember, Vue, etc.) d'être explorés sans pénalité de la part de Google.
Au-delà de la recherche, d'autres robots d'exploration Web sont également importants pour la visibilité de votre site, à savoir les riches robots de partage social qui s'appuient sur des balises méta restent aveugles à JavaScript.
Dans ce didacticiel, nous allons créer un module alternatif de routage et de rendu pour vos serveurs Express et Node.js que vous pouvez utiliser avec la plupart des frameworks SPA et permettre à votre site Web d'être présenté sur Twitter, Facebook et Pinterest Share richement.
Ce tutoriel est dédié aux robots Web qui extraient des informations socialement partagées. N’essayez pas cette technique avec les robots des moteurs de recherche. Les sociétés de moteurs de recherche peuvent prendre ce comportement au sérieux et le considérer comme du spam ou de la fraude, de sorte que votre classement peut chuter rapidement.
De même, avec un partage social riche, assurez-vous que le contenu que vous présentez est cohérent avec ce que les utilisateurs voient et ce que lisent les robots. Le non-respect de cette cohérence peut entraîner des restrictions sur les sites de médias sociaux.
Si vous publiez une mise à jour sur Facebook et incluez une URL, le bot Facebook lira le code HTML et recherchera la balise méta OpenGraph. Voici un exemple de la page d'accueil d'Envato Tuts+ :
Inspectez la page, dans la balise head
, voici les balises pertinentes qui ont généré cet aperçu :
Pinterest utilise le même protocole que Facebook et OpenGraph, leur partage fonctionne donc à peu près de la même manière.
Sur Twitter, ce concept est appelé « cartes » et Twitter propose quelques variantes différentes selon la manière dont vous souhaitez présenter votre contenu. Voici un exemple de carte Twitter de GitHub :
Voici le HTML qui génère cette carte :
Remarque : GitHub utilise une technologie similaire à celle décrite dans ce tutoriel. Le HTML de la page diffère légèrement des balises dont l'attribut name est défini sur twitter:description
. J'ai dû modifier l'agent utilisateur comme décrit plus loin dans cet article pour obtenir les balises méta correctes.
Si vous n'avez besoin que d'un titre, d'une description ou d'une image pour l'ensemble de votre site Web, l'ajout de balises méta n'est pas un problème. Codez simplement ces valeurs en dur dans le head
du document HTML. Cependant, vous créez peut-être un site Web plus complexe et souhaitez que le partage social riche varie en fonction de l'URL (il peut s'agir d'un wrapper pour l'API d'historique HTML5 sur laquelle votre framework fonctionne).
Un premier essai pourrait consister à créer un modèle et à ajouter la valeur à la balise méta, comme vous ajouteriez n'importe quoi d'autre. Étant donné que le robot qui extrait ces informations n'exécute pas JavaScript à ce stade, vous vous retrouvez avec la balise de modèle au lieu de la valeur attendue lorsque vous essayez de partager.
Pour rendre le site Web lisible par les robots, nous construisons un middleware pour détecter l'agent utilisateur des robots de partage social, puis construisons un routeur de secours pour fournir aux robots le contenu correct, évitant ainsi l'utilisation de frameworks SPA.
Les clients (bots, robots d'exploration Web, navigateurs) envoient la chaîne de l'agent utilisateur (UA) dans l'en-tête HTTP de chaque requête. Cela devrait identifier le logiciel client ; même si les navigateurs Web disposent d'une grande variété de chaînes UA, les robots ont tendance à être plus ou moins stables. Facebook, Twitter et Pinterest publient les chaînes d'agent utilisateur de leurs robots à titre gracieux.
Dans Express, les chaînes UA sont disponibles en tant qu'objets user-agent
包含在 req
uest. J'utilise des expressions régulières pour identifier les différents robots auxquels je souhaite fournir du contenu alternatif. Nous l'inclurons dans le middleware. Les middlewares sont comme des routes, mais ils ne nécessitent pas de chemin ou de méthode, et ils transmettent (généralement) la demande à un autre middleware ou route. Dans Express, les routes et le middleware sont contigus, placez-les donc au-dessus de toutes les autres routes dans votre application Express.
app.use(function(req,res,next) { var ua = req.headers['user-agent']; if (/^(facebookexternalhit)|(Twitterbot)|(Pinterest)/gi.test(ua)) { console.log(ua,' is a bot'); } next(); });
L'expression régulière ci-dessus recherche "facebookexternalhit", "Twitterbot" ou "Pinterest" au début de la chaîne UA. S'il est présent, l'UA sera connecté à la console.
Voici l'intégralité du serveur :
var express = require('express'), app = express(), server; app.use(function(req,res,next) { var ua = req.headers['user-agent']; if (/^(facebookexternalhit)|(Twitterbot)|(Pinterest)/gi.test(ua)) { console.log(ua,' is a bot'); } next(); }); app.get('/',function(req,res) { res.send('Serve SPA'); }); server = app.listen( 8000, function() { console.log('Server started.'); } );
Dans Chrome, accédez à votre nouveau serveur (il devrait être http://localhost:8000/
). Ouvrez DevTools et activez le mode appareil en cliquant sur l'icône du smartphone dans le coin supérieur gauche du volet développeur.
在设备工具栏上,将“Twitterbot/1.0”放入UA编辑框中。
现在,重新加载页面。
此时,您应该在页面中看到“Serve SPA”,但是查看 Express 应用程序的控制台输出,您应该看到:
Twitterbot/1.0 是一个 bot
现在我们可以识别机器人了,让我们构建一个备用路由器。 Express 可以使用多个路由器,通常用于按路径划分路由。在这种情况下,我们将以稍微不同的方式使用路由器。路由器本质上是中间件,因此除了 req
、res
和 next
之外,就像任何其他中间件一样。这里的想法是生成一组具有相同路径的不同路由。
nonSPArouter = express.Router(); nonSPArouter.get('/', function(req,res) { res.send('Serve regular HTML with metatags'); });
我们的中间件也需要更改。现在,我们不再只是记录客户端是机器人,而是将请求发送到新路由器,重要的是,如果 UA 测试失败,则仅将其与 next()
一起传递。因此,简而言之,机器人获得一台路由器,其他人获得为 SPA 代码提供服务的标准路由器。
var express = require('express'), app = express(), nonSPArouter = express.Router(), server; nonSPArouter.get('/', function(req,res) { res.send('Serve regular HTML with metatags'); }); app.use(function(req,res,next) { var ua = req.headers['user-agent']; if (/^(facebookexternalhit)|(Twitterbot)|(Pinterest)/gi.test(ua)) { console.log(ua,' is a bot'); nonSPArouter(req,res,next); } else { next(); } }); app.get('/',function(req,res) { res.send('Serve SPA'); }); server = app.listen( 8000, function() { console.log('Server started.'); } );
如果我们使用与上面相同的例程进行测试,将 UA 设置为 Twitterbot/1.0
浏览器将在重新加载时显示:
使用元标记
提供常规 HTML
使用标准 Chrome UA,您将获得:
服务SPA
正如我们上面所讨论的,丰富的社交共享依赖于 HTML 文档头部内的 meta
标签。由于您正在构建 SPA,因此您甚至可能没有安装模板引擎。在本教程中,我们将使用玉。 Jade 是一种相当简单、诱人的语言,其中空格和制表符是相关的,并且不需要结束标签。我们可以通过运行来安装它:
npm 安装jade
在我们的服务器源代码中,在 app.listen
之前添加此行。
app.set('视图引擎', '玉石');
现在,我们将仅输入想要提供给机器人的信息。我们将修改 nonSPArouter
。由于我们已经在应用程序集中设置了视图引擎,因此 res.render
将进行玉石渲染。
让我们设置一个小玉模板来服务于社交共享机器人:
doctype html html head title= title meta(property="og:url" name="twitter:url" content= url) meta(property="og:title" name="twitter:title" content= title) meta(property="og:description" name="twitter:description" content= descriptionText) meta(property="og:image" content= imageUrl) meta(property="og:type" content="article") meta(name="twitter:card" content="summary") body h1= title img(src= img alt= title) p= descriptionText
这个模板的大部分内容是 meta
标签,但您也可以看到我在文档正文中包含了这些信息。在撰写本教程时,似乎没有一个社交共享机器人实际上会查看元标记之外的任何其他内容,但如果在以下位置实施任何类型的人工检查,则最好以某种人类可读的方式包含信息:稍后的日期。
将模板保存到应用程序的 view
目录并将其命名为 bot.jade
。不带扩展名的文件名(“bot”)将是 res.render 函数的第一个参数。
虽然在本地开发总是一个好主意,但您将需要在其最终位置公开您的应用程序以完全调试您的 meta
标记。我们的小型服务器的可部署版本如下所示:
var express = require('express'), app = express(), nonSPArouter = express.Router(), server; nonSPArouter.get('/', function(req,res) { var img = 'placeholder.png'; res.render('bot', { img : img, url : 'https://bot-social-share.herokuapp.com/', title : 'Bot Test', descriptionText : 'This is designed to appeal to bots', imageUrl : 'https://bot-social-share.herokuapp.com/'+img }); }); app.use(function(req,res,next) { var ua = req.headers['user-agent']; if (/^(facebookexternalhit)|(Twitterbot)|(Pinterest)/gi.test(ua)) { console.log(ua,' is a bot'); nonSPArouter(req,res,next); } else { next(); } }); app.get('/',function(req,res) { res.send('Serve SPA'); }); app.use('/',express.static(__dirname + '/static')); app.set('view engine', 'jade'); server = app.listen( process.env.PORT || 8000, function() { console.log('Server started.'); } );
另请注意,我使用 express.static
中间件来提供 /static
目录中的图像。
将应用程序部署到可公开访问的位置后,您应该验证您的 meta
标记是否按预期工作。
首先,您可以使用 Facebook 调试器进行测试。输入您的网址并点击获取新的抓取信息。
您应该看到类似以下内容:
接下来,您可以继续使用 Twitter 卡验证器测试您的 Twitter 卡。对于此操作,您需要使用 Twitter 帐户登录。
Pinterest 提供了一个调试器,但此示例无法开箱即用,因为 Pinterest 只允许在主页以外的 URL 上使用“丰富的 pin”。
Dans la mise en œuvre réelle, vous devez gérer l'intégration des sources de données et le routage. C'est une bonne idée de revoir les itinéraires spécifiés dans le code SPA et de créer des versions alternatives de tout ce qui, selon vous, pourrait être partagé. Une fois que vous avez établi un itinéraire pour un éventuel partage, configurez une balise meta
dans votre modèle principal qui vous servira de solution de repli si quelqu'un partage une page dont vous n'avez pas l'intention.
Bien que Pinterest, Facebook et Twitter représentent une grande partie du marché des médias sociaux, il existe d'autres services que vous souhaiterez peut-être intégrer. Certains services publient les noms de leurs robots de partage social, d'autres non. Pour déterminer l'agent utilisateur, vous pouvez console.log
et vérifier la sortie de la console - essayez d'abord ceci sur un serveur hors production, car essayer de déterminer l'agent utilisateur peut être difficile sur un site occupé. À partir de ce moment, vous pouvez modifier l'expression régulière dans notre middleware pour capturer le nouvel agent utilisateur.
Le partage riche sur les réseaux sociaux est un excellent moyen d'attirer les gens vers votre magnifique site Web basé sur une application d'une seule page. En dirigeant sélectivement les robots vers du contenu lisible par machine, vous pouvez fournir aux robots les bonnes informations.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!