利用PhantomJS為SPA做SEO

利用PhantomJS為SPA做SEO

利用PhantomJS為SPA做SEO

隨著前端技術的不斷更新,使用前端框架(React、Vue等)來建構網站是普遍現象。但目前搜尋引擎無法有效讀取使用JavaScript render出來的頁面,且使用AJAX Crawling的解法只適用於Google又此法已被廢棄,因此另一解法就是使用PhantomJS。

這裡使用 Node.js + PhantomJS 為SPA/以Ajax讀取資料的頁面做SEO。

說明

以下程式碼是我為某個頁面寫的範例。

頁面載入時會用ajax取得一行字串「今天吃飯,該吃什麼好呢?只要輸入美食欲望,立刻給你最真實、現場、生活化的評價,找餐廳再也不煩惱,就讓吃什麼,どっち幫你決定吃什麼!」,然後append到畫面上。

程式流程:當讀取頁面的時候,先去判斷是不是robot,如果是robot,就使用PhantomJS丟給它已讀取好的靜態頁面內容,說白話些就是預先載入頁面後取得頁面內容;如果不是robot,就走一般的流程,也就是render樣版。

PhantomJS和Node.js是不相容的,因此使用了一個中間橋梁phantom - Fast NodeJS API for PhantomJS。但這不是官方的,可能會因為各種原因崩解。

程式碼

var express = require('express'),
    router = express.Router(),
    phantom = require('phantom'),
    fs = require('fs');

router.get('/', function(req, res, next) {
  var ua = req.headers['user-agent'],
      fullUrl = req.protocol + '://' + req.get('host') + req.originalUrl,
      pattern = /Googlebot|Googlebot-News|Googlebot-Image|Googlebot-Video|Googlebot-Mobile|Mediapartners-Google|Mediapartners|AdsBot-Google|AdsBot-Google-Mobile-Apps/i,
      isRobot = pattern.test(ua);

  if(isRobot) {
    var sitepage = null,
        phInstance = null;

    phantom.create().then(function (instance) {
      phInstance = instance;
      return instance.createPage();
    }).then(function (page) {
      sitepage = page;
      return page.open(fullUrl);
    }).then(function (status) {
      return sitepage.property('content');
    }).then(function (content) {
      res.send(content);
      sitepage.close();
      phInstance.exit();
    }).catch(function (error) {
      console.log(error);
      phInstance.exit();
    });
  } else {
    res.render('system', {
      title: '吃什麼,どっち',
      description: '今天吃飯,該吃什麼好呢?只要輸入美食欲望,立刻給你最真實、現場、生活化的評價,找餐廳再也不煩惱,就讓吃什麼,どっち幫你決定吃什麼!'
    });
  }
});

router.post('/getInfo', function(req, res, next) {
  res.json({
    isSuccess: true,
    response: '今天吃飯,該吃什麼好呢?只要輸入美食欲望,立刻給你最真實、現場、生活化的評價,找餐廳再也不煩惱,就讓吃什麼,どっち幫你決定吃什麼!'
  });
});

module.exports = router;

測試結果

未經過PhantomJS加入與修改之前

未經過PhantomJS加入與修改之前,robot只能看到這樣的狀況--經由Ajax取得資料後append到畫面上的區塊是空的。

利用PhantomJS為SPA做SEO

PhantomJS加入與修改之後

一般使用者(非robot)檢視原始碼時會看到這樣的狀況,經由Ajax取得資料後append到畫面上的區塊依然是空的。

利用PhantomJS為SPA做SEO

但...使用webmaster的測試工具來測,robot可以檢視到經由Ajax取得資料後append到畫面上的文字。

利用PhantomJS為SPA做SEO

總結:優缺比較

優點

可讓robot讀取由JavaScript render的頁面。

缺點

每一次robot來訪時,就會執行兩次回應:一次是robot讀取頁面,一次是PhantomJS打開頁面 (程式碼中 return page.open(fullUrl) 這一行),增加Server端的負擔。並且,phantomjs打開頁面後產生的靜態內容是每次都會重新產生的。

由於這些缺點,因此還找了其他解法使用。例如:使用Prerender.io或自己實作後端render的服務,後續會有相關文章說明和實驗。

推薦閱讀

參考資料


由於部落格搬家了,因此在新落格也放了一份,未來若有增刪會在這裡更新-利用 PhantomJS 為 SPA 做 SEO
張貼留言