2021-02-03 10:48:16
单页面应用现如今成为了网站的主流,前端框架三剑客React、Vue、Angular基本形成三足鼎立之势。这些框架所带来的的编程体验以及高效的研发效率是不可否认的,但是也有一大缺点就是对于搜索引擎十分的不友好,如果用来做一个后端管理系统来说,无需考虑SEO,十分完美。但是作为前端网站来说,搜索引擎对于流量起着至关重要的作用。
一般情况,我们这些单页面应用都是直接从服务器推送index.html,再根据自身路由通过js在客户端浏览器渲染出完整的html页面。当前搜索引擎中google可以实现抓取js渲染的页面,其他的搜索引擎基本上就GG了。
当然,三大框架也给出了相应的方式来处理服务器端渲染,比如react提供了renderToString,react自带的renderToString 和 renderToStaticMarkup 可以用来将组件(Virtual DOM)输出成 HTML 字符串,但是个人总觉得在写法上不爽,写代码的时候会有多余的顾虑。
网上还有其他的一些方案比如基于react的nextjs,基于VUE的nuxtjs,但是这些框架基本上还是变回了之前的多页面模式,还增加了一定的框架学习成本,另外还有一点就是写起来不爽!而且如果改现有的网站,呵呵呵~~~
如果你想使用可以自行网上搜索,有大把的教程可以看,官方也提供了相应的文档。
之前我也写过一篇关于服务器渲染的文章,但是有很大的局限性,有兴趣的朋友可以去看一看vue/react服务端渲染实例
这里我想说另一个解决方案,无论是对于现有的网站还是新开发的网站来说都是一样的,简单快捷,他就是—— Rendertron
Rendertron
Rendertron是nodejs框架下的产物,是google-chrome旗下的的配套产品。首先,服务器上装有个google-chrome,rendertron把他打开,然后在服务器(官方推荐express)中增加中间件,先判断UA(user-agent)里面有没有带有类似Baiduspider(百度爬虫)等字样,如果没有,就像正常的单页面服务器那样,把原始html推送出去,由客户端浏览器完成js、css渲染的工作;如果带有指定UA头字样,就先把网页推送给本地服务器那个google-chrome,等他渲染好对应页面后,把渲染好的html结果推送出去。这样在写网站的时候无需有其他的顾虑,可以想怎么写就怎么写,只有当爬虫过来的时候将渲染好的页面吐给他即可,其他用户访问正常,没有任何影响,是不是很爽
基本的运行流程如下图所示:
好了,说了很多下面我们来实际搭建一下,将其运行起来看效果。
安装Chromeheadless
网上有很多教程写如何安装,我觉得我们还是用最简单的一个方式吧,使用脚本安装
代码语言:javascript复制curl https://intoli.com/install-google-chrome.sh | bash
https://intoli.com 这个网站是专门从事headless browsers使用简化,提供云服务的一家公司。其中在该公司的博客中,可以看到许多关于Google Chrome的文章。
该公司提供的这个脚本,能够自动查找相关依赖,并安装。这样我们就不必担心依赖问题,导致无法安装成功。
安装Rendertron
这个安装有两种方式,一种通过npm直接全局安装
代码语言:javascript复制npm install -g rendertron
但是安装过程不会很顺利如果你不会访问外国网站的话,没关系,官方为我们提供了另外一个方法:
代码语言:javascript复制git clone https://github.com/GoogleChrome/rendertron.git
嗯~~~ 我想说这个也很麻烦,下载超级慢,不知道是为啥,而且很容易下载失败,你可以登录上去下载压缩包试试,大概率是可以成功的。
然后我们进入到rendertron目录,执行下面的命令:
代码语言:javascript复制npm install
npm run build
pm2 start bin/rendertron
当build的时候可能会出现报错,但是我实际使用的时候发现好像不影响.....。他其实就是一个node项目,我们用pm2来启动他。
项目引用
这里我们使用的是express框架,在你的express服务器程序中引入中间件rendertron-middleware,需要先进行安装
代码语言:javascript复制npm install --save express rendertron-middleware
然后再app.js中进行使用
代码语言:javascript复制const rendertron = require('rendertron-middleware');
const app = express();
app.use(rendertron.makeMiddleware({
proxyUrl: 'http://localhost:3000/render',
}));
rendertron默认启动是使用3000端口,如果你想修改端口号,可以在build目录中找到config.js在里面你可以看到修改的位置。
rendertron还有一些其他的配置项:
代码语言:javascript复制app.use(rendertron.makeMiddleware({
proxyUrl: 'http://localhost:3000/render',
userAgentPattern:****,
excludeUrlPattern:****,
timeout:11000,//这个timeout超时参数亲测已经无效了,可以直接删了,在config.js中直接修改就好
}));
userAgentPattern是用来写清楚哪些UA头需要服务器渲染,除此之外的请求都直接单页面推送。比如这样写:
代码语言:javascript复制const botUserAgents = [
'Baiduspider',
'bingbot',
'Embedly',
'facebookexternalhit',
'LinkedInBot',
'outbrain',
'pinterest',
'quora link preview',
'rogerbot',
'showyoubot',
'Slackbot',
'TelegramBot',
'Twitterbot',
'vkShare',
'W3C_Validator',
'WhatsApp',
];
app.use(rendertron.makeMiddleware({
//其他参数
userAgentPattern: new RegExp(botUserAgents.join('|'), 'i'),
}));
把你要的爬虫UA头都写到一个数组里,然后用new RegExp()正则一下
excludeUrlPattern是指哪些文件格式需要在chromeheadless中被完全加载,用法如下
代码语言:javascript复制const staticFileExtensions = [
'ai', 'avi', 'css', 'dat', 'dmg', 'doc', 'doc', 'exe', 'flv',
'gif', 'ico', 'iso', 'jpeg', 'jpg', 'js', 'less', 'm4a', 'm4v',
'mov', 'mp3', 'mp4', 'mpeg', 'mpg', 'pdf', 'png', 'ppt', 'psd',
'rar', 'rss', 'svg', 'swf', 'tif', 'torrent', 'ttf', 'txt', 'wav',
'wmv', 'woff', 'xls', 'xml', 'zip',
];
//略n行代码
app.use(rendertron.makeMiddleware({
//其他参数
excludeUrlPattern: new RegExp(`\.(${staticFileExtensions.join('|')})$`, 'i'),
}));
把你需要加载的文件后缀都写到一个数组里,然后用new RegExp()正则一下
至此我们的搭建工作就完成了,使用pm2来启动express服务器,然后来进行一下测试:
命令行输入curl -A “baiduspider” http://你需要测试的网址(就是访问你的server程序对应的那个网址,即改写前的那个原来的网址),然后就能看到通过chromeheadless渲染好的html代码,大功告成!
或者你可以直接使用postman访问,但是要记得将user-agent修改一下。
本文参考链接:https://blog.csdn.net/grootxu59/article/details/90453679