使用Prerender.io進行網站預渲染

抓住驚魚的熊發表於2019-06-17

前言

使用Angular,Vue,React進行單頁網站開發,使用者瀏覽時瀏覽器動態解析JS,呈現出最終的頁面,使用者體驗比較好,網站效能也提高不少。

但網路爬蟲並不會動態解析Js,訪問所有URL得到的只會是專案入口檔案中的程式碼,不能得到具體的內容,也就無法做網站SEO。

使用Prerender.io做網站預渲染,可以將網站頁面渲染之後再返回給網路爬蟲,間接完成網頁的解析。 Prerender相較於其他的解決方案,配置相對要簡單一些,不用修改專案原始碼,程式碼零侵入,是一個不錯的解決方案。

目標

搭建基於Centos 7 和 Nginx 環境的Prerender渲染服務,完成Angular專案中網頁的預渲染

預渲染流程圖

執行流程
執行流程

安裝中介軟體

  1. 首先註冊登入 Prerender.io,並且獲得個人token
    token
    token
  2. 根據開發文件,配置對應的中介軟體,如Nginx,Apache等。
  3. 配置Nginx中介軟體,參考配置如下:
server {
    listen 80;
    server_name example.com;
 
    root   /path/to/your/root;
    index  index.html;

    location / {
        try_files $uri @prerender;
    }
 
    location @prerender {
        # 將 YOUR_TOKEN替換為你的個人token
        proxy_set_header X-Prerender-Token YOUR_TOKEN;
        
        set $prerender 0;
        if ($http_user_agent ~* "googlebot|bingbot|yandex|baiduspider|twitterbot|facebookexternalhit|rogerbot|linkedinbot|embedly|quora link preview|showyoubot|outbrain|pinterest|slackbot|vkShare|W3C_Validator") {
            set $prerender 1;
        }
        if ($args ~ "_escaped_fragment_") {
            set $prerender 1;
        }
        if ($http_user_agent ~ "Prerender") {
            set $prerender 0;
        }
        if ($uri ~* "\.(js|css|xml|less|png|jpg|jpeg|gif|pdf|doc|txt|ico|rss|zip|mp3|rar|exe|wmv|doc|avi|ppt|mpg|mpeg|tif|wav|mov|psd|ai|xls|mp4|m4a|swf|dat|dmg|iso|flv|m4v|torrent|ttf|woff|svg|eot)") {
            set $prerender 0;
        }
        
        #resolve using Google's DNS server to force DNS resolution and prevent caching of IPs
        resolver 8.8.8.8;
 
        if ($prerender = 1) {
            
            # 後續將service.prerender.io替換為自己的prerender服務,如127.0.0.1:3000
            set $prerender "service.prerender.io";
            rewrite .* /$scheme://$host$request_uri? break;
            proxy_pass http://$prerender;
        }
        if ($prerender = 0) {
            rewrite .* /index.html break;
        }
    }
}
複製程式碼

參考配置:gist.github.com/thoop/81658…

  1. 檢測nginx配置,並重啟nginx
nginx -t
service nginx restart
複製程式碼
  1. 中介軟體安裝完成

安裝Prerender服務

  1. 在伺服器上安裝Node環境

  2. 下載Prerender服務

git clone https://github.com/prerender/prerender.git
複製程式碼

若沒有安裝git服務,可手動從Github下載再上傳到/usr資料夾下,再解壓到當前目錄下 3. 安裝npm依賴

cd /usr/prerender
# Phantomjs 官方的下載地址會超時,此處重新指定其下載地址為淘寶映象
export PHANTOMJS_CDNURL=https://npm.taobao.org/mirrors/phantomjs
npm install
複製程式碼

檔案結構如下:

檔案結構
檔案結構

  1. 執行server.js
# 啟動Server.js, 預設監聽3000埠
node server.js
複製程式碼

此時,如果預先沒有安裝過Chrome,則會啟動失敗 提示啟動Chrome失敗,未檢測到Chrome,此時安裝Chrome就好了 為什麼要安裝Chrome呢,因為Prerender並不負責真正的網頁解析,Prerender只負責解析前後的處理,實際是由Chrome負責網頁的解析。

安裝Chrome

  1. 配置yum源 因為國內無法訪問Google,所以需要自己配置yum源,在目錄 /etc/yum.repos.d/ 下新建google-chrome.repo檔案
cd /ect/yum.repos.d/
touch google-chrome.repo
複製程式碼
  1. 寫入內容 vi google-chrome.repo
[google-chrome]
name=google-chrome
baseurl=http://dl.google.com/linux/chrome/rpm/stable/$basearch
enabled=1
gpgcheck=1
gpgkey=https://dl-ssl.google.com/linux/linux_signing_key.pub
複製程式碼
  1. 安裝執行
# 國內推薦
yum -y install google-chrome-stable --nogpgcheck
複製程式碼
  1. 安裝路徑 安裝成功後,Chrome的安裝路徑應該是 /opt/google/chrome 預設情況下,root使用者不能直接執行chrome,所以可以新建另一個使用者如other來執行
cd /opt/google/chrome
su other
./chrome
複製程式碼
  1. Chrome安裝完成

啟動Prerender.io服務

  1. 已other使用者再次執行server.js
su other
cd /usr/prerender
node ./server.js
複製程式碼

此時應該是可以成功啟動的,並且可以看到該服務監聽3000埠 啟動結果:

啟動結果
啟動結果
2. 修改nginx配置

if ($prerender = 1) {
            
           # 修改如下:
            # set $prerender "service.prerender.io";
            set $prerender "127.0.0.1:3000";
            rewrite .* /$scheme://$host$request_uri? break;
            proxy_pass http://$prerender;
        }
複製程式碼
  1. 儲存重啟Nginx
  2. 再次啟動Prerender服務
nohup node ./server.js &
複製程式碼

其中nohup命令是將該服務加入守護程式,避免ssh對話視窗關閉導致服務關閉,參考Linux設定Jar後臺執行

  1. 如果開啟了防火牆,需要將3000埠加入防火牆
firewall-cmd —zone=public —add-port=3000/tcp —permanent
# 重啟防火牆
firewall-cmd —reload
複製程式碼
  1. 至此,Prerender服務已經安裝並啟動成功
  2. 檢視埠
    檢視埠
    檢視埠
    Node,Google-Chrome,Nginx服務都應在後臺執行

測試

If you use html5 push state (recommended):
Just add this meta tag to the <head> of your pages

<meta name="fragment" content="!"> 
複製程式碼
If your URLs look like this:
http://www.example.com/user/1 

Then access your URLs like this:
http://www.example.com/user/1?_escaped_fragment_=
複製程式碼
If you use the hashbang (#!):
If your URLs look like this:
http://www.example.com/#!/user/1 

Then access your URLs like this:
http://www.example.com/?_escaped_fragment_=/user/1
複製程式碼
通過curl命令測試
curl http://www.example.com/user/1?_escaped_fragment_=
複製程式碼

在配置prerender服務前,以上返回的只是index.html的內容, 如果配置成功則會返回解析後的內容。

相關文章