node.js 程序
单页应用程序(SPA)由客户端呈现模板提供支持,从而为最终用户带来非常动态的体验。 最近, Google宣布他们 以正常用户的身份对 网页进行爬网并执行JavaScript ,从而使由SPA框架(包括Angular,Ember和Vue等)提供支持的网站受到爬网,而不会受到Google的惩罚 。
除搜索之外,其他Web爬网程序对您网站的可见性也很重要-即依靠元标记的丰富的社交共享机器人仍然对JavaScript不了解。
在本教程中,我们将为Express和Node.js服务器构建一个备用路由和渲染模块,您可以将其与大多数SPA框架一起使用,并使您的网站能够在Twitter,Facebook和Pinterest上进行丰富的共享。
警告语
本教程专门讨论提取社交共享信息的网络机器人。 不要对搜索引擎网络搜寻器尝试这种技术。 搜索引擎公司可以认真对待这种行为 ,并将其视为垃圾邮件或欺诈行为 ,因此,您的排名可能会Swift下降。
同样,通过丰富的社交共享信息,请确保您以一种使用户看到的内容与机器人读取的内容对齐的方式来表示内容。 未能保持这种一致性可能会导致社交媒体网站的限制。
丰富的社交分享
如果您在Facebook中发布更新并包含URL,Facebook机器人将读取HTML并查找OpenGraph meta标签。 这是Envato Tuts +主页的示例:
检查页面的head
标签中,以下是生成此预览的相关标签:
Pinterest使用与Facebook OpenGraph相同的协议,因此它们的共享工作原理大致相同。
在Twitter上,该概念称为“卡片”,根据您想要呈现内容的方式,Twitter有几个不同的品种。 这是来自GitHub的Twitter卡的示例:
这是生成此卡片HTML:
注意:GitHub正在使用与本教程中描述的技术类似的技术。 页面HTML在name属性设置为twitter:description
的标记中略有不同。 我必须按照本文后面所述更改用户代理,以获取正确的meta标签。
客户端渲染的优势
如果您只需要整个网站的一个标题,描述或图像,则添加元标记不是问题。 只需将值硬编码到HTML文档的head
。 但是,您可能正在构建一个复杂得多的网站,并且希望您的丰富社交共享根据URL(可能是框架要处理的HTML5历史API的包装)而变化。
第一个尝试可能是构建模板,然后将值添加到meta标记中,就像处理其他任何内容一样。 由于此时,提取此信息的漫游器不会执行JavaScript,因此在尝试共享时,最终将获得模板标签而不是预期的值。
为了使机器人可以读取该站点,我们正在构建一个中间件,该中间件检测社交共享机器人的用户代理,然后构建一个备用路由器,为机器人提供正确的内容,从而避免使用您的SPA框架。
用户代理中间件
客户端(机器人,网络爬虫,浏览器)在每个请求的HTTP标头中发送用户代理(UA)字符串。 应该用来识别客户端软件; 虽然网络浏览器具有多种UA字符串,但机器人通常或多或少是稳定的。 Facebook,Twitter和Pinterest出于礼貌发布了其机器人的用户代理字符串。
在快递,UA串被包含在req
uest对象作为user-agent
。 我正在使用正则表达式来确定我对提供替代内容感兴趣的不同漫游器。 我们将其包含在中间件中。 中间件就像路由,但是它们不需要路径或方法,并且(通常)将请求传递给另一个中间件或路由。 在Express中,路由和中间件是顺序的,因此请将其放在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();
});
上面的正则表达式在UA字符串的开头查找“ facebookexternalhit”,“ Twitterbot”或“ Pinterest”。 如果存在,它将UA登录到控制台。
这是整个服务器:
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.');
}
);
测试您的中间件
在Chrome中,导航到新服务器(应为http://localhost:8000/
)。 打开DevTools并通过单击开发人员窗格左上方的智能手机图标打开“设备模式”。
在设备工具栏上,将“ Twitterbot / 1.0”放入UA编辑框中。
现在,重新加载页面。
此时,您应该在页面中看到“ Serve SPA”,但是在查看Express应用程序的控制台输出时,您应该看到:
Twitterbot/1.0 is a 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
则浏览器将在重新加载时显示:
Serve regular HTML with metatags
使用标准的Chrome UA,您将获得:
Serve SPA
元标记
如上所述,丰富的社交共享依赖于HTML文档头部内的meta
标记。 由于您正在构建SPA,因此甚至可能没有安装模板引擎。 在本教程中,我们将使用玉器。 Jade是一种非常简单的诱人语言,其中空格和制表符相关,并且不需要结束标记。 我们可以通过运行以下命令进行安装:
npm install jade
在我们的服务器源代码中,将此行添加到您的app.listen
之前。
app.set('view engine', 'jade');
现在,我们将仅将要提供给机器人的信息输入。 我们将修改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
标签,但是您也可以看到我在文档正文中包含了这些信息。 在撰写本教程时,社交共享机器人似乎都没有真正看过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 Debugger进行测试。 输入您的URL,然后单击获取新的抓取信息 。
您应该看到类似以下内容:
接下来,您可以继续使用Twitter Card Validator测试Twitter卡 。 为此,您需要使用您的Twitter帐户登录。
Pinterest提供了一个调试器 ,但是此示例无法立即使用,因为Pinterest仅允许在首页以外的URL上使用“丰富的图钉”。
下一步
在实际的实现中,您需要处理数据源和路由的集成。 最好查看SPA代码中指定的路由,并为您认为可能共享的所有内容创建备用版本。 在建立了可能会共享的路由之后,请在主模板中设置meta
标记,以在有人共享您未曾期望的页面的情况下作为您的后备。
尽管Pinterest,Facebook和Twitter占据了社交媒体市场的很大一部分,但您可能还需要集成其他服务。 某些服务确实会发布其社交共享机器人的名称,而其他服务则可能不会。 要确定用户代理,您可以console.log
并检查控制台输出-首先在非生产服务器上尝试此操作,因为在确定繁忙站点上的用户代理时可能会花费很多时间。 从那时起,您可以在我们的中间件中修改正则表达式以捕获新的用户代理。
丰富的社交媒体份额可能是吸引人们进入您喜欢的基于单页应用程序的网站的好方法。 通过有选择地将机械手定向到机器可读的内容,您可以向机械手提供正确的信息。
node.js 程序