事情是這樣的
最近公司需要做一個(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)有找到很好方法,故希望此文能幫到需要的人