vue網(wǎng)站SEO優(yōu)化持續(xù)踩坑(PhantomJS)

事情是這樣的

最近公司需要做一個(gè)網(wǎng)頁(yè)導(dǎo)航 集成文章功能的網(wǎng)站,不想重復(fù)造輪子,于是乎就在gitee上扒了一個(gè)開(kāi)源的項(xiàng)目來(lái)改造。項(xiàng)目前端架構(gòu)是vue+elementui。
千辛萬(wàn)苦在項(xiàng)目收尾階段,老板突然說(shuō)網(wǎng)站要做SEO。到時(shí)沒(méi)多想,就覺(jué)的不就是seo嘛,加上關(guān)鍵字、描述標(biāo)題不就完事了,然后項(xiàng)目匆匆上線了。過(guò)了一陣子才不慌不忙的開(kāi)始著手seo的事,當(dāng)我在瀏覽器右鍵查看網(wǎng)站源碼的時(shí)候,傻眼了,整個(gè)網(wǎng)站的body里只有一個(gè)醒目的div,如下

<body>
  <div id="app"></div>
</body>

WTF...
才想起來(lái),vue頁(yè)面是在前端渲染的,果斷度娘了一波,一大片說(shuō)vue不友好之類的,看完我差點(diǎn)昏厥。
好在遇到同樣問(wèn)題的不止我一個(gè),找到了一些vue項(xiàng)目做seo優(yōu)化的解決方案,于是乎我順著前人的腳步,一步步開(kāi)啟了我的seo踩坑之旅。

選方案

網(wǎng)上找到的方案大致分四類,包括SSR服務(wù)器渲染,靜態(tài)化以及服務(wù)器無(wú)頭瀏覽器等,優(yōu)劣不一,各有千秋,筆者綜合考慮自身情況,選擇最后一種,用PhantomJs針對(duì)爬蟲(chóng)做處理。
詳細(xì)請(qǐng)參考:http://www.fly63.com/article/detial/3960

PhantomJs初使用

Phantomjs是一個(gè)基于webkit內(nèi)核的無(wú)頭瀏覽器,即沒(méi)有UI界面,即它就是一個(gè)瀏覽器,只是其內(nèi)的點(diǎn)擊、翻頁(yè)等人為相關(guān)操作需要程序設(shè)計(jì)實(shí)現(xiàn)。這種解決方案其實(shí)是一種旁路機(jī)制,原理就是通過(guò)Nginx配置,將搜索引擎的爬蟲(chóng)請(qǐng)求轉(zhuǎn)發(fā)到一個(gè)node server,再通過(guò)PhantomJS來(lái)解析完整的HTML。
這里有一個(gè)方案可參考:http://www.itdecent.cn/p/2bbbc2fcd16d

但是筆者按照上述方案操作的時(shí)候,會(huì)報(bào)一個(gè)Cannot find module 'express'的錯(cuò)誤,查了一下,是需要安裝express。
自己當(dāng)時(shí)太菜,并不知道express是個(gè)什么鬼,所以選了另外一種方法,在github上找了一套別人打包好的vue-seo-phantomjs

按照上述操作,最后執(zhí)行

phantomjs spider.js 'https://wj.qq.com/'

的時(shí)候,成功出現(xiàn)網(wǎng)站的html信息了。
但是仔細(xì)一看,發(fā)現(xiàn)還是沒(méi)有渲染的頁(yè)面,報(bào)錯(cuò)信息是

phantonjs ReferenceError: Can't find variable: Promise

Promise的坑

老辦法,找度娘...
筆者在這一塊卡了一上午時(shí)間,踩了很多坑,甚至硬著頭皮查閱了老外的討論和筆記https://github.com/ariya/phantomjs/issues/12401
最后大概了解,應(yīng)該是還差一個(gè)Promise的依賴。
解決辦法:在你的vscode(就是你的開(kāi)發(fā)工具)的終端輸入

npm install es6-promise --save

然后在你項(xiàng)目的js中加入一串代碼

import Promise from 'es6-promise'
Promise.polyfill()

筆者是加在項(xiàng)目的main.js里,然后重新打包,部署,最后終于看見(jiàn)了渲染后的頁(yè)面,激動(dòng)的眼眶都紅了

等等,還沒(méi)結(jié)束呢。到這一步,可能大部分朋友已經(jīng)OK,但是可能部分小朋友的項(xiàng)目的代碼寫的不規(guī)范,或者濫用組件的原因,導(dǎo)致用phantomjs渲染的時(shí)候報(bào)錯(cuò),這時(shí),就要根據(jù)報(bào)錯(cuò)信息逐個(gè)解決,一般報(bào)錯(cuò)信息是在你執(zhí)行 phantomjs spider.js '你的url' 之后會(huì)打印出來(lái)。
在此筆者會(huì)列出自己遇到的問(wèn)題

URLSearchParams 坑

報(bào)錯(cuò)信息:

[root@VM-0-10-centos phantomjs]# phantomjs spider.js 'http://106.52.91.112:9527/#/info?blogUid=fc654f40718341ef01edf13ce71f1fea'
[Vue warn]: Error in created hook: "ReferenceError: Can't find variable: URLSearchParams"

found in

---> <Info>
       <Index>
         <App>
           <Root>

  https://cdn.bootcdn.net/ajax/libs/vue/2.5.17/vue.js:597 in warn
ReferenceError: Can't find variable: URLSearchParams
解決辦法1

棄用URLSearchParams。在vue項(xiàng)目中,注釋所有URLSearchParams相關(guān)用法,采用直接傳匿名對(duì)象

          // var params = new URLSearchParams();
          // params.append("uid", this.blogUid);
          getBlogByUid({uid: this.blogUid}).then(response => {
            if (response.code == this.$ECode.SUCCESS) {
              this.blogData = response.data;
            }
            setTimeout(()=>{
              that.blogContent = response.data.content
              that.loadingInstance.close();
            }, 200)
          });

Nginx配置

upstream spider_server {
    server localhost:8081;
}
server {
    listen       80;
    server_name  www.lidh.vip;
    
    location / {
      proxy_set_header  Host            $host:$proxy_port;
      proxy_set_header  X-Real-IP       $remote_addr;
      proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;

      if ($http_user_agent ~* "Baiduspider|twitterbot|facebookexternalhit|rogerbot|linkedinbot|embedly|quora link preview|showyoubot|outbrain|pinterest|slackbot|vkShare|W3C_Validator|bingbot|Sosospider|Sogou Pic Spider|Googlebot|360Spider") {
        proxy_pass  http://spider_server;
      }
      
      # vue項(xiàng)目路徑
      root   /opt/proj/kehai/goxp_nav/vue_web/dist;
      index  index.html index.htm;
    }
}

結(jié)束語(yǔ)

小菜鳥(niǎo)筆者的踩坑日常,讓大佬見(jiàn)笑了,本文旨在幫助那些遇到同樣問(wèn)題的人能避免入坑,因?yàn)樽约涸谶@個(gè)坑花了太久時(shí)間,然后網(wǎng)上也沒(méi)有找到很好方法,故希望此文能幫到需要的人

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容