本文主要介绍Vue SSR(vue服务端渲染)的应用场景,开发中容易遇到的一些问题,提高ssr性能的方法,以及ssr的安全性问题。html
SSR的应用场景前端
1.SEO需求vue
SEO(Search Engine Optimization,搜索引擎优化),是一种利用搜索引擎规则,提升网站在搜索引擎内天然排名的技术。一般这须要页面内容在页面加载完成时便已经存在。SEO需求的存在与互联网技术的发展历程密不可分。在互联网产生之初,网页使用超文本连接协议,将服务器的信息传递给客户端。然后出现了专门为人们检索信息的搜索引擎。随着前端技术的不断发展,出现了先后端分离的纯前端项目,因为这类项目须要页面加载完成后再异步获取数据渲染,所以大部分搜索引擎没法获取到这类项目的内容。Vue SSR正是基于此类需求而给出的一种技术方案。利用nodejs搭建页面渲染服务,在服务端完成以前须要在客户端完成的页面渲染工做,输出给SEO更友好的页面。node
除Vue SSR方案外,也能够选择Prerender(https://github.com/prerender/prerender)做为替代方案。Prerender和Vue SSR的相同点是都须要在服务端完成页面的渲染,不一样点在于Prerender采用无界面虚拟浏览器Phantomjs去渲染输出页面,而Vue SSR是基于vue组件的渲染。相比来讲Prerender的通用性更强,任何页面都适用,而Vue SSR则只适用于vue项目,但因为Vue SSR是基于代码层面的直接渲染,不须要像Prerender那样再去拉取静态资源,所以速度更快。ios
至于应该使用哪种技术方案,就要视需求和实际状况取舍了。git
2.首屏渲染速度github
如在上面SEO需求中提到的,目前先后端的分离的前端项目须要先加载静态资源,再异步获取数据,最后渲染页面,在这个过程当中的前两部页面都是没有数据的,影响了首屏的渲染速度,也就影响了用户的体验。 目前对于首屏渲染速度的提高有许多方案,在ssr以外还有龙骨,墓碑,数据直出。相比于这些方案ssr方案实现是最复杂的,但效果也是最好的。sql
下图是项目使用服务端渲染先后的首屏加载时间对比,能够明显看出服务端渲染将白屏时间和首屏完成渲染的时间都减小了50%左右。vuex
3.Vue SSR方案的选择axios
目前Vue SSR的实现有两种实现,一种是基于官方Vue SSR指南文档的官方方案,一种是vue.js通用应用框架--NUXT。 官方方案具备更直接的控制应用程序的结构,更深刻底层,更加灵活,同时在使用官方方案的过程当中,也会对Vue SSR有更加深刻的了解。 而NUXT提供了平滑的开箱即用的体验,它创建在同等的Vue技术栈之上,但抽象出不少模板,并提供了一些额外的功能,例如静态站点生成。经过NUXT能够根据约定的规则,快速的实现Vue SSR。
开发中容易遇到的一些问题
1.一套代码两套执行环境
vue的生命周期钩子函数中, 只有 beforeCreate和 created 会在服务器端渲染(SSR)过程当中被调用,这就是说在这两个钩子函数中的代码以及除了vue生命周期钩子函数的全局代码,都将会在服务端和客户端两套环境下执行。若是在两套环境的代码中加入具备反作用的代码或访问特定平台的API,将出现各类问题。好比服务端没有window、document对象, 若是加了对这个对象的引用和操做,将在服务端引发报错中断。
所以,总结起来,最容易犯的错误就是不判断环境就去使用window、document对象。
解决方案:
(1)在beforeCreate,created生命周期以及全局的执行环境中调用特定的api前须要判断执行环境;
(2)使用adapter模式,写一套adapter兼容不一样环境的api。
2.服务端数据的预获取
官方方案使用Vuex在服务端预获取数据。 在服务端添加vue钩子函数,获取数据后,将数据保存在vuex的store结构中,同时渲染页面。
在数据预获取阶段注册的钩子函数中,最好只进行数据的获取和保存,不进行其余任何涉及this的操做。由于此时的this是服务端的this,是全部用户共享的this,进行操做将发生一些不可预知的错误。
举个例子,好比想在数据预获取的钩子函数中操做data数据。 首先,数据预获取的钩子函数在运行时尚未vue的实例,所以根本拿不到关于vue实例的任何东西;其次,进行的存取操做都是在全部用户的公共变量下进行的,一旦成功进行了存取操做,必然是全部用户的存取操做。
同时须要注意的是,vuex在Vue SSR方案下,应使用惰性注册的方案。若是不使用惰性注册方案,而是在一开始vuex初始化实例的时候就把全部的模块统一注册,将会出现多个页面共用许多模块的问题。
如咱们有store模块以下:
则在路由组件内,须要按以下代码惰性注册vuex模块
总结起来就是,在服务端预获取数据的钩子函数中,不要进行额外的操做,任何对于数据的额外操做都要在vuex的体系下进行,vuex在Vue SSR方案下,应使用惰性注册的方案。
3.接口代理的问题
因为前端平时开发时的接口不少都是线下的,所以须要对于接口的地址进行代理切换。咱们平时用的最多的是fiddler和charles等端口代理软件。可是ssr在数据预获取时走的是服务端,不是浏览器,所以不能经过这两个工具进行代理。
办法有两个,一个是修改服务器的host地址,这个方法在开发阶段只须要更改本机的host就好,可是在提测阶段须要修改服务器的host,若是两个项目在同一个机器上测试,将不可避免的形成冲突。 第二个方法是使用axios的代理功能,由于axios对于ssr有自然的适配性,所以99%的项目都会用它。而它自带的proxy功能,能够帮助咱们方便的作接口代理。
代理配置文件以下:
代理设置代码以下:
4.cookie穿透
因为客户端的http请求首先达到SSR服务器,再由SSR服务器去后端服务器获取相应的接口数据。在客户端到SSR服务器的请求中,客户端是携带有cookie数据的。可是在SSR服务器请求后端接口的过程当中,倒是没有相应的cookie数据的。所以在SSR服务器进行接口请求的时候,咱们须要手动拿到客户端的cookie传给后端服务器。这里若是使用是axios,就能够手动设置axios请求的headers字段,达到cookie穿透的目的。
5.路由模式
vue有两种路由模式,一种是hash模式,就是咱们常常用的#/hasha/hashb这种,还有一种是history模式,就是/historya/historyb这种。由于hash模式的路由提交不到服务器上,所以ssr的路由须要采用history的方式。
异常处理问题
1.异常来自哪里?
(1)服务端数据预获取过程当中的异常,如接口请求的各类异常,获取到数据后对数据进行操做的过程当中出现的错误异常。
(2)在服务端数据预获取的生命周期结束后的渲染页面过程当中出现的异常,包括各类操做数据的语法错误等,如对undefined取属性。
2.怎么处理异常
(1)官方处理方法
抛出500错误页面,体验不友好,产品不接受。
(2)目前采用的方法
a.服务端数据预获取过程当中出现的异常,让页面继续渲染,不抛出500异常页面,打错误日志,接入监控。同时,在页面加入标志,让前端页面再次进行一次数据获取页面渲染的尝试。
b.页面渲染过程的异常。因为目前渲染过程是vue提供的一个插件进行的,异常很差捕获,同时出现问题的几率不是很大,所以尚未作专门的处理。
代码以下:
entry-server.js服务端部分:
index.template.html页面模板部分增长以下js代码:
entry-client.js客户端部分:
总结:总结起来一句话,为了更好的体验,不要出现500。
性能
ssr能够提升首屏加载的速度,减小白屏时间,经过如下设置能够提升性能,减小服务器资源的占用,加快访问速度。
(1)页面级别的缓存 将渲染完成的页面缓存到内存中,同时设置最大缓存数量和缓存时间。 优点:大幅度提升页面的访问速度 代价:增长服务器内存的使用
(2)组件级别的缓存 适用:纯静态组件,v-for中循环的子组件
(3)接口级别的缓存
安全
由于作了node服务,所以安全方面也须要考虑。
(1)DDOS攻击
最基本的DDOS攻击就是利用合理的服务请求来占用过多的服务资源,从而使合法用户没法获得服务的响应
应对:
1.提高硬件设备
硬件性能越好,提供的服务并发能力越强,这样即便有小量的DDOS攻击也能够不影响正经常使用户的访问。
2.在服务端只作最基本的处理
在服务端不作过多复杂的数据处理,能够有效的提升ssr的性能。
3.日志只打印关键部位的关键信息
打印日志过多将耗费服务器资源,影响服务器的性能。
4.DDOS流量清洗
部署流量清洗相关设备,能够对网络中的DDoS攻击流量进行清除,同时保证正常流量的经过。
5.DDOS软硬件防火墙
软件防火墙解决方案为将软件防火墙部署到被保护的服务器上,优势是成本低、方便、灵活,缺点是做用有限、占用资源。
硬件防火墙解决方案为安装防火墙硬件,优势是效果好,缺点是成本高。
(2)sql注入
就是经过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令 例如: 游戏pc详情页的代码为http://game.zhuanzhuan.com/detail/1001306437923405830?metric=e32aeb1b742c27af0ec80cef4b51b654
而攻击者将url替换为http://game.zhuanzhuan.com/detail/select%20*%20from%20user?metric=e32aeb1b742c27af0ec80cef4b51b654
应对:
1.对参数进行校验
在服务端的entry文件中添加校验代码,执行组件的校验规则
(3)数据泄露
使用vuex的状况下,若是不使用惰性加载,容易形成数据泄露的状况发生。
关于任何须要登陆获取数据的状况,建议不在服务端进行,只在客户端进行
做者:ChokCoco
原文:www.cnblogs.com/coco1s/p/8882542.html