單頁應用程式 (SPA) 由客戶端呈現範本提供支持,為最終用戶提供非常動態的體驗。最近,Google 宣布他們會像一般使用者一樣抓取網頁並執行 JavaScript,從而使 SPA 框架(Angular、Ember 和 Vue 等)支援的網站在不受 Google 懲罰的情況下進行抓取。
除了搜尋之外,其他網路爬蟲對於您網站的可見性也很重要,即依賴元標記的豐富社交分享機器人仍然對 JavaScript 視而不見。
在本教學中,我們將為您的Express 和Node.js 伺服器建立一個備用路由和渲染模組,您可以將其與大多數SPA 框架一起使用,並使您的網站能夠在Twitter、Facebook 和Pinterest 上進行豐富的分享。
本教學專門討論提取社交分享資訊的網路機器人。 不要在搜尋引擎網路爬蟲中嘗試這種技巧。 搜尋引擎公司可能會認真對待這種行為,並將其視為垃圾郵件或詐欺行為,因此您的排名可能會很快下降。
同樣,透過豐富的社交分享訊息,請確保您所呈現的內容與使用者所看到的內容與機器人所讀到的內容保持一致。未能保持這種一致性可能會導致社交媒體網站的限制。
如果您在 Facebook 中發布更新並包含 URL,Facebook 機器人將讀取 HTML 並尋找 OpenGraph 元標記。以下是 Envato Tuts 主頁的範例:
#檢查頁面,在 head
標籤中,以下是產生此預覽的相關標記:
Pinterest 使用與 Facebook、OpenGraph 相同的協議,因此它們的共享工作原理大致相同。
在 Twitter 上,這個概念被稱為“卡片”,並且 Twitter 有幾種不同的變體,具體取決於您想要如何呈現內容。以下是來自 GitHub 的 Twitter 卡範例:
#這是產生此卡片的 HTML:
注意:GitHub 使用與本教程中描述的類似技術。頁面 HTML 與名稱屬性設定為 twitter:description
的標籤略有不同。我必須按照本文後面所述更改用戶代理才能獲得正確的元標記。
如果您只需要整個網站的一個標題、描述或圖像,添加元標記不是問題。只需將這些值硬編碼到 HTML 文件的 head
中即可。然而,您可能正在建立一個更複雜的網站,並且您希望豐富的社交分享根據 URL 的不同而變化(這可能是您的框架正在操作的 HTML5 History API 的包裝器)。
第一次嘗試可能是建立範本並將值新增至元標記,就像新增任何其他內容一樣。由於此時提取此資訊的機器人不會執行 JavaScript,因此在嘗試共享時,您最終會得到模板標籤,而不是預期的值。
為了讓網站能夠被機器人讀取,我們正在建立一個中間件來檢測社交共享機器人的用戶代理,然後建立一個備用路由器,為機器人提供正確的內容,從而避免使用 SPA 框架。
客戶端(機器人、網路爬蟲、瀏覽器)在每個請求的 HTTP 標頭中傳送使用者代理程式 (UA) 字串。這應該可以識別客戶端軟體;雖然網頁瀏覽器有各種各樣的 UA 字串,但機器人往往或多或少都穩定。 Facebook、Twitter 和 Pinterest 出於禮貌發布其機器人的用戶代理字串。
在 Express 中,UA 字串作為 user-agent
包含在 req
uest 物件中。我使用正規表示式來識別我有興趣提供替代內容的不同機器人。我們將把它包含在中間件中。中間件就像路由,但它們不需要路徑或方法,它們(通常)會將請求傳遞給另一個中間件或路由。在 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 是一个 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”。
在實際實作中,您需要處理資料來源和路由的整合。最好查看 SPA 程式碼中指定的路由,並為您認為可能共享的所有內容建立替代版本。建立可能共用的路由後,在主範本中設定 meta
標記,當有人共用您不想要的頁面時,該標記可作為您的後備。
雖然 Pinterest、Facebook 和 Twitter 佔據了社群媒體市場的很大一部分,但您可能還想整合其他服務。有些服務確實會公佈其社交共享機器人的名稱,而其他服務則可能不會。要確定使用者代理,您可以 console.log
並檢查控制台輸出 - 首先在非生產伺服器上嘗試此操作,因為在繁忙的網站上嘗試確定使用者代理可能會很困難。從那時起,您可以修改我們的中間件中的正規表示式來捕獲新的用戶代理程式。
豐富的社群媒體分享是將人們吸引到您精美的基於單頁應用程式的網站的好方法。透過選擇性地將機器人引導至機器可讀的內容,您可以向機器人提供正確的資訊。
以上是增強 Node.js 單頁應用程式中的社交共享的詳細內容。更多資訊請關注PHP中文網其他相關文章!