利用 Prerender Node 為 SPA 做 SEO
16 Sep 2016圖片來源:Wake Up, SEOs – the NEW New Google is Here。
繼利用 PhantomJS 為 SPA 做 SEO 又來一個為 SPA 解決 SEO 問題的解法。
如何使用 Prerender Node?
依照官方文件操作 Prerender Node,並設定 app.js 如下:
var prerender = require('prerender-node');
app.use(prerender);
prerender
.set('beforeRender', function(req, done) {
console.log('before render');
done(null, 'Hello');
})
.set('afterRender', function(err, req, prerender_res) {
console.log('after render');
});
beforeRender
是指 robot 來爬,但尚未 render 頁面給 robot 之前的動作,通常在這裡設定將要回傳的快取頁面;afterRender
是指回傳 robot 後的動作,通常用來將頁面做快取以備之後使用。在這邊先回傳簡單的字串 Hello
,前面的 null 表示沒有錯誤。
訊息如下。
頁面出現剛剛設定的 Hello
字串。
讀取快取頁面
經過了剛剛簡單回傳字串的方式,當然我們也可以設定回傳一個已經快取好的頁面index_cached.html
。
設定
prerender
.set('beforeRender', function(req, done) {
fs.readFile('./public/index_cached.html', 'utf8', function(err, data) {
if (err) {
console.log(err);
done();
} else {
done(null, data);
}
});
})
.set('afterRender', function(err, req, prerender_res) {
console.log('after render');
});
快取頁面
快取頁面的程式碼如下,這不是一個真的快取頁面噢,只是範例檔。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Hello</title>
</head>
<body>
<h1>Hello</h1>
</body>
</html>
頁面出現剛剛設定的快取頁面。
也可以使用Redis等來做快取頁面。
var prerender = require('prerender-node'),
redis = require('redis'),
client = redis.createClient();
app.use(prerender);
prerender
.set('beforeRender', function(req, done) {
client.get(req.url, done);
})
.set('afterRender', function(err, req, prerender_res) {
client.set(req.url, prerender_res.body);
});
原理
看了原始碼之後,Prerender Node 的運作方式是這樣的
- 檢查 User Agent 中的字串是否有 robot 名稱(檢查對象有 Googlebot、Bingbot 等,但是寫死在程式碼裡面的,無法新增),如果有符合的 robot 名稱,就回傳快取頁面。
- 如果 URL 中含有
_escaped_fragment_
,就表示是 robot,要回傳頁面。 - 檢查頁面是否在白名單或黑名單裡面。若是 robot 要求且在白名單裡面,就回傳頁面;如果是 robot 要求但在黑名單裡面,就不要回傳頁面。
- 若 robot 請求的是頁面而非資源(例如,附檔名為 .js、.css 的檔案,這部份也是寫死的),則回傳頁面。
備註
如果測試的時候發現怎麼頁面對常用的 Googlebot 都沒有反應,這是因為prerender-node
的index.js
這個檔案把我們常用的 Googlebot 等都註解掉了,記得要打開才會看到正確的執行結果。
作者註解這一段的原因有寫在程式碼裡面
// googlebot, yahoo, and bingbot are not in this list because
// we support _escaped_fragment_ and want to ensure people aren't
// penalized for cloaking.
大意是說,因為支援偵測 URL 是否含有 _escaped_fragment_
且為了避免網站被誤認為黑帽技法而被懲罰,因此註解起來。但_escaped_fragment_
已被 google 廢棄,並且在此對於 robot 或使用者我並沒有回傳不同的內容(只是 render 的方式不同,一個是後端,一個是前端),所以就手動打開吧。
總結
與利用 PhantomJS 為 SPA 做 SEO 比較起來,這次使用 Prerender Node 解決了執行兩次回應和每次都會重新產生靜態檔案(而能使用快取頁面)的問題,相較之下是更能減輕 server 端負擔。而且,更模組化的包裝起來了。
同場加映,自己建立 Prerender 服務!
自己建立 Prerender 服務
如果只是小小的部落格網站,使用 Prerender.io 這個服務即可,但免費帳號是有快取頁數限制的。若頁面數量很大,就可以利用它們的開源專案自己架一個服務來用。
Step 1:下載 Prerender Service。在 local 端 run 起來 http://localhost:3000
會看到以下訊息:
Step 2:在自己的專案修改 app.js,修改 port 號,將 port 3000 讓給 Prerender,自己的專案改用 8080。
app.set('port', process.env.PORT || 8080);
var server = app.listen(app.get('port'), function() {
console.log('Ready on port ' + server.address().port);
});
Step 3:在瀏覽器鍵入 http://localhost:3000/http://localhost:8080
來看看結果,可以利用自己建立的服務看到自己的專案了。
這篇文章的原始位置在這裡-利用 Prerender Node 為 SPA 做 SEO
由於部落格搬遷至此,因此在這裡放了一份,以便閱讀;部份文章片段也做了些許修改,以期提供更好的內容。