关于大型网站技术演进的思考(十五)--网站静态化处理—前后端分离—中(7)

  上篇里我讲到了一种前后端分离方案,这套方案放到服务端开发人员面前比放在web前端开发人员面前或许得到的掌声会更多,我想很多资深前端工程师看到这样的技术方案可能会有种说不出来的矛盾心情,当我的工作逐渐走向越来越专业化的前端开发后,我就时常被这套前后端分离方案所困惑,最近我终于明白了这个困惑的本源在哪里了,那就是这套前后端分离方案其实是服务端驱动的前后端分离方案,它的实现手段又是从服务端的MVC架构体系演化而来,因此该方案最大的问题就是它并没有从根本上改变web前端从属于服务端的被动局面。那么问题来了,有没有以web前端为驱动的前后端分离方案呢,该方案能让web前端的能力获得更大的释放了?答案是绝对有。本篇就要讲讲以web前端驱动的前后端分离方案

  首先要提的就是javascriptMVC,下面我摘抄的是维基百科里对javascriptMVC的解释,具体如下:

  首先是简介:

JavaScriptMVC 是一套开放源代码的多样化互联网应用程序框架,以 jQuery 与 OpenAJAX 为基础。JavaScriptMVC 利用 MVC 架构与工具扩展这些函式库,以便开发与测试。由于 JavaScriptMVC 不需要任何服务器端的配合,因此它可以和任何的网站服务接口与编程语言整合,如 ASP.NET、Java、Perl、PHP、Python 或 Ruby。

 

  接下来是历史:

JavaScriptMVC 的第一个版本是在2008年5月释出。稳定版的 JavaScriptMVC 2.0 在2009年6月释出,并以 jQuery 为基础。主要开发目标为维持程式码的简短和专注在它独特的功能上。3.0版本在2010年12月释出。而从 JavaScriptMVC 中所独立出来的 MVC 架构“CanJS”则在2012年4月释出。

  从维基百科里的解释我们会发现如下启示,它们分别如下:

  启示一:javascriptMVC是一个应用框架的名字,这和jQuery的命名是一样的,所以这里我要声明一下,本系列里的javascriptMVC不是指代这个框架,而是指代的是使用javascript语言实现出的一类的web前端的MVC框架,本系列后面的javascriptMVC和前端MVC的含义是一致的。

  启示二:从javascriptMVC历史里我们可以看到第一版的javascriptMVC产生于2008年,这个历史要远早于nodejs出现的时间,这说明了前端的MVC并不是因为nodejs的出现而产生的,应该是nodejs推动了前端的MVC框架的应用和普及。

  启示三:维基百科里有一段解释:

由于 JavaScriptMVC 不需要任何服务器端的配合,因此它可以和任何的网站服务接口与编程语言整合,如 ASP.NET、Java、Perl、PHP、Python 或 Ruby。

 

  这段话说明了前端MVC的一个很重要的特点就是前端MVC可以摆脱服务端语言的束缚做到真正的独立,同时前端MVC又可以和任何服务端语言进行整合,大家可以试想下如果我们开发的web应用前端达到了前端MVC的程度,那么公司在招聘web前端工程师的时候就不在会问你“你会java吗?”或者“你会php吗?”假如这个前端工程师所会的服务端语言能力和公司不匹配,面试官也不会再犹豫和摇头了。

  启示三同时还隐含了一个问题,为什么好的前端MVC框架可以做到和任何服务端语言配合呢?这个解决手段之一我在前文中的第一阶段前后端分离方案里就提到了,那就是解决报文格式的统一和交互接口的统一的技术手段,只有这样前端MVC和服务端的灵活对接就不会再是问题了。但是仅仅这个手段还是远远不够的,我们要达到这个需求还需要解决一个问题,这个问题就是要把服务端MVC霸占web前端的工作也要抢回来。那如何抢呢?

  上篇文章里我分析过服务端MVC的视图层的问题,服务端MVC的视图层技术例如java里的jsp技术,这个技术是将html和java代码整合的技术,java的web容器把jsp解析完毕后最终生成为html文件发送给浏览器,浏览器在解析这个html将最终效果展示给用户。那么我们要抢回服务端霸占的web前端的工作我们就得分析下这些动态页面技术到底做了哪些事情特别是侵占web前端的事情。

  这里首先我们要谈谈服务端在动态页面里的作用,其实服务端为动态页面作用很单一就是提供了网站需要展示的数据而已,服务端是不会创造一个新页面的。服务端提供的数据的类型也是很统一,要不就是服务端语言提供的基本数据类型例如:字符、数字、日期等等,要不就是复杂点的数据类型例如数组、列表、键值对等等,不过归属服务端的动态页面还需要服务端语言帮助做一件事情,那就是把服务端提供的数据整合到页面里,最终产生一个浏览器可以解析的html网页,这个操作无非就是使用服务端语言可以构造文件的能力构建一个符合要求的html文件而已。不过一个页面里需要动态变化的往往只是其中一部分,所以做服务端的动态页面开发时候我们可以直接写html代码,这些html代码就等于在构造页面展示的模板而已,而模板的空白处则是使用服务端数据填充,因此在java的web开发里视图层技术延生出了velocity,freemark这样的技术,我们将其称之为模板语言的由来。

  由此可见,服务端MVC框架里抢夺的web前端的工作就是抢占了构建html模板的工作,那么我们在设计web前端的MVC框架时候对于和服务端对接这块只需要让服务端保持提供数据的特性即可。从这些论述里我们发现了,其实前端MVC框架要解决的核心问题应该有这两个,它们分别是:

  核心问题一:让模板技术交由浏览器来做,让服务端只提供单纯的数据服务。

  核心问题二:模板技术交由浏览器来承担,那么页面的动态性体现也就是根据不同的服务端数据进行页面部分刷新来完成的。

  而这两个核心问题解决办法那就是使用ajax技术,ajax技术天生就符合解决这些问题的技术手段了。

  要让web前端承担模板技术,就得使用javascript的模板技术,时下javascript的模板技术可谓是百花齐放,百家争鸣,很多朋友曾为这些技术称奇,其实探求它的本源无非就是用javascript为基础实现了个jsp,velocity而已,如果有朋友还没接触过javascript模板技术,可以在百度里搜索下【javascript模板引擎】,本文这里就不展开谈论了。

  前端的MVC讨论到这里又出现了一个新的疑问,我上面讲到解决前端MVC两大核心问题的手段是ajax技术,ajax是异步请求,那么这是不是就是说让网站全部使用异步请求我们就可以实现前端MVC,并且解决网站所有的问题呢?

  这个问题的回答当然是不可能的。一个网站是永远没法摆脱与异步请求相对的同步请求,就算有个网站把异步做到了极致,但是它也无法摆脱用户第一次访问要在浏览器地址栏填写网站入口页面url地址的同步请求问题,网站把异步操作做到极致也无非就是把网站做成了一个纯粹的单页面形式而已。

  纯粹单页面的网站很多人一听到就觉得好牛逼啊,很前卫,很厉害,对前端有所了解的人还会想到单页面也就意味要运用更多的javascript编程和DOM编程,前端代码难度也会大大增强,好的单页面应用如果这个应用还包含复杂的业务逻辑,那么单页面前端开发里很可能还会使用到如今很火爆的javascript模块技术例如requirejs或者seajs技术,单页面听起来实在太完美了,但是我们冷静下来思考下,单页面真的完美吗?下面我要为单页面泼泼凉水了,具体如下:

  泼凉水一:单页面其实指的是网站只有一个入口,但是并不代表用户看到的网页就是一个样子的,单页面里也会有很多页面切换,但是不管页面里的模样如何变化,浏览器地址栏的地址都不会变化,能做到这点就得归功ajax的超强能力了,单页面不同模样的展示都是在javascript代码里实现的,那么问题来了,单页面对于搜索引擎的网络爬虫就非常不友好了,因为网络爬虫是根据url抓取页面,抓取完毕后会忽略javascript代码,那么单页面的设计方案就会导致SEO优化只能作用于首页,而网站其他页面将无非有效的被SEO技术进行优化。

  泼凉水二:一个网站做成单页面以后那么网站不同的展示都在一个url下面,但是如果有些用户只是对网站的某一部分功能很感兴趣,而这部分功能又不是被单页面的唯一同步请求所展示的首页里的内容,那么结果就是这些用户每次登陆网站时候都要手动操作一下才能进入自己想要的功能页面里,假如首页进入功能页面的操作步骤比较繁琐,那么这个必然会导致网站用户体验的下降。

  那么上面的问题该如何来破呢?

  这里我首先来讲讲第二个问题的解决方案,第二个泼凉水的问题的核心就是要记录单页面的状态问题,这个状态可以帮助首页能快速切换到具体的功能页面,要让客户端网页有状态最常用的手段就是cookie了,如果浏览器支持html5,那么保存状态的手段就更多,能力也更强了。但是这种手段是和客户端紧耦合的,那么如果碰到这种情况,该手段就会出现问题了,例如如果有个人发现单页面网站里一个很有趣的功能,这时候他正好和朋友QQ聊天,他告诉了他的朋友,他的朋友也该兴趣,让他把链接发过来,那么这个朋友就不得不在从首页在重复操作一遍,由此可见,cookie的手段并没有全面解决这个问题,那我们还有其他手段嘛?

  答案是还真有,那就是使用html的锚链接,锚链接的形式如下所示:

http://www.baidu.com/#sharpxiajun

 

  下面是我摘抄下百度百科对锚链接的解释:

锚链接实际上就是链接文本,又叫锚文本。可以理解为:带有文本的超链接,就叫锚链接。锚文本可以作为文本链接所在的页面的内容的评估。

一般的来讲,网站页面中增加的锚链接都和页面本身的内容有一定的必然联系。网站建设的行业网站上会增加一些同行网站的链接或者一些做网站建设的知名设计网站的链接;

另一方面,锚文本能作为对所指向页面的评估。锚文本能精确的描述所指向页面的内容,个人网站上增加Google的链接,锚文本为 “搜索引擎”。这样通过锚文本本身就能知道,Google是搜索引擎。

 

  那么在单页面里的功能切换时候我们改变一下url上的锚文字,反过来说使用锚文字做路由器,让其可以路由到对应的功能页面那么上面的问题不就可以解决了。关于锚链接我这里要补充一些知识,首先锚链接的形式是url#文字,锚的起始标记是#号,这个#号的内容其实是属于浏览器端的,也就是说#包括#号后面的内容是不会被发送到服务端的,那么我们想改变锚链接只能在客户端进行,但是传统的锚链接的变化是很难被javascript语言监控到的,直到html5的出现才从根本上解决了这个问题,html5提供了hashchange事件,该事件可以监控锚链接的变化,因为javascript语言可以监控锚链接的变化,那么使用锚链接路由功能页面就成为了可能,那么低版本的浏览器该怎么办了?这个主要是ie的问题了,其实ie8包括ie8都支持hashchange事件,再低就不行了,不过jQuery有个插件可以让低版本的ie支持hashchange事件,有兴趣的童鞋可以百度下啊。

  看来泼凉水二问题是有解的,那么泼凉水一怎么解决了?我的回答是基本无解,这个问题的关键在网络爬虫这边,如果我们被动解决这个问题,那只能是抛弃javascript了,这个玩笑就开大了,所以我们只好祈求各大搜索引擎能不能智能化再厉害点了。这里加个题外话,我最近几天突然意识到一个问题,那就是讲到web前端技术我一定要加强对SEO的思考,因为绝大多数网站都会把搜素引擎当做入口的生命线,这是一个很难回避的问题,不管我们网站做的如何优秀,假如用户很难找到它,那一切都将会是百搭,而在前端设计里要加入SEO的思考,这必然会导致整个架构的重大变化。这个问题我会在以网站静态化角度审视前后端分离方案时候重点讲下。

  前端MVC讨论到这里我们会发现我们的谈论里缺了一环那就是MVC的M层模型层,web前端要侵入到模型层了,这不就等于web前端要造反了,它不仅仅想改变从属服务端的悲惨命运,还要抢夺服务端的部分功能,让服务端成为浏览器对应的存储系统,这不是无异于虎口夺食,在时下服务端如此强势的大环境下,这种想法简直就是活得不耐烦了,哈哈,当然这是戏言了,做技术做工程还是要讲求个合理性和逻辑性的,技术和工程都是实在的东西很讲道理的,只要道理站得住脚怎么个做法都是其次,回到问题本身,我个人觉得在PC端讨论web前端做模型层其实往往利大于弊,就安全而言,模型层意味有大量业务逻辑推移到web前端,那么安全的保障难度会加大,就技术难度而言,web前端做模型层会让javascript编程巨复杂,所以要做这个抉择时候一定要结合业务做仔细的权衡,其实我现在接触的一些说包含模型层能力的前端框架在实际运用里模型层的功能还是使用太少,不过这个问题如果放到移动端,或者是PC和移动端融合可能就会有些不同,这个问题我将在本系列的终篇里再谈谈,这里也不累述了。

  说到这里需要总结下了,前端的MVC不应该等于单页面开发,前端MVC也不是把ajajx用到极致,根据实际业务场景,我们需要适当的把同步请求和异步请求结合起来。如果前端MVC里包含了更多同步请求,那么对于MVC里的C层即控制层就会有更高的要求。前后端分离主题还有个下篇,下篇里我还会提到一种前后端分离方案那就是nodejs的运用,而nodejs的运用就是和控制层有密切的关系,上篇里我提到nodejs是前后端分离方案的催化剂,其实我个人认为nodejs参入的前后端分离方案才是更加完美些的前后端分离方案,这个完美的评价原因之一就是从前端承担控制层作用角度思考的,所以前端控制层这个内容我将放在下篇讨论。

  好了,本篇写完了,从本篇我们可以看到前端MVC的历史很早,它的出现早于nodejs,这就说明前端MVC其实并不是什么新技术,只不过是现在才被大家重视起来,完善它的人也越来越多。从本篇我们还发现前端MVC其实并不完美,问题很多,最致命的就是对网络爬虫的不友好,所以我们需要考虑到SEO技术参入其中的前后端分离方案。

  最后,祝大家晚安了。

posted @ 2015-02-27 23:07  夏天的森林  阅读(7569)  评论(14编辑  收藏  举报