说起前后端分离,大家包括我自己都会想到:

当今流行的MVC不就是最标准的前后端分离吗?

说到这里,我不禁要反问,MVC真正的实现了前后端分离了吗?

无论是PHP的MVC框架TP还是JAVA的MVC框架SpringMVC,他们实现的前后端分离或许应该被叫做:一定程度上的逻辑和展示的分离

当然我们不能泯灭MVC带来的贡献,MVC的出现让写代码不再是一行写到底,他给我们带来了分层的概念,并在一定的程度上减少了三层间的纠缠。

但是,我们回忆一下当我们基于MVC写代码的时候,是不是有这样的情况:

这样的一个新闻列表(html+php)

<div class="news">

<?php

foreach($results as $item){

?>

<li class='news_item'><a href="<?php echo $item['url'];?>"><?php echo $item['title'];?></a></li>

<?php

}

?>

</div>

或则是:这样的一个分页(jsp)

<table>

<tr><th>名字</th><th>说明</th><th>图片预览</th></tr>

<c:forEach items="${data}" var="item">

<tr><td>${item.advertName}</td><td>${item.notes}</td><td><img src="${item.defPath}"/></td></tr>

</c:forEach>

</table>

<ul>

<li><a href='?nowPage=${nowPage-1}'>上一页</a></li>

<c:forEach varStatus="i" begin="1" end="${sumPage}"> <c:choose> <c:when test="${nowPage==i.count}">

<li class='disabled'>${i.count}</li>

</c:when>

<c:otherwise>

<li class='active'><a href='?nowPage=${i.count}'>${i.count}</a></li>

</c:otherwise>

</c:choose>

</c:forEach>

<li><a href='?nowPage=${nowPage+1}'>下一页</a></li>

</ul>

在这些个项目中我们的开发人员就是在view层不断的“挖坑”和不断的“填坑”,而且虽然我们用到MVC框架,但是我们并没有真正的实现前后端分离。

如何实现前台人员就写前台,后台人员只管后台,这是我一直在思考的问题。

无论是为了满足业务上的需求:比如,前端变化频繁,或者前端效果要求非常高/跨设备的兼容性要求很高的情况下

还是为了使技术团队更加精进所在领域,团队分工更加明确,能和需求更好对接(界面问题归前台,业务功能开发归后台)的角度来看,我觉得做好前后端分离,是团队建设的很重要的一部。

当然这也是在公司有一定经济基础的条件下,我也是一个实用主义者,提倡为了业务而技术,而不是为了技术而技术。

------------------------说了这么多,大多都是我个人开发中遇到的一些情况和问题,下面开始正题了----------------------

听闻淘宝引入Nodejs来实现了淘宝团队的前后端分离,下面就看看常见的做法和淘宝的做法,供大家思考

web架构的发展经历了(也可以说正在经历)从后端为主MVC应用时代---->基于Ajax的SAP应用时代---->以前端为主的MV*时代---->基于Nodejs的全栈时代

这个过程也是随着经济发展,人们对审美,性能要求不断提升而发展来的。

在各个时代前后端配合的方式也不一样,分别看一下:

后端为主MVC应用时代

  在MVC架构中一般是前端人员写模板,给后台人员套用,这就是上面说的那种情况,前后台纠缠不清,到最后就是大家一起写了,前台后台一起大包干,根本没有分工了。

基于Ajax的SAP应用时代

  随着2004年gmail的诞生,随后也诞生了Ajax,它的到来让SPA疯狂了一把,这个时代前后台分工还算是很明晰的,后台提供接口,前台来调用。  

  同时也带来了一大堆的问题,前端代码过于复杂,而且前台严重依赖后端接口,如果后端数据模型不稳定经常变化,那么前台开发人员就会很痛苦,所谓牵一发动全身。可维护性很差,而且代码难修改。

以前端为主的MV*时代

  前几年出现了各种前端框架,有mvc的Backone,有MVVM的angularjs等。。。

  这些框架总的原则是先按类型分层,比如 Templates、Controllers、Models,然后再在层内做切分,

  这个时代的应用实现了前后端分离,前端工作在浏览器端,后端工作在服务端。清晰的分工,可以让开发并行,测试数据的模拟不难,前端可以本地开发。后端则可以专注于业务逻辑的处理,输出 RESTful 等接口。

  但是,这种应用全是异步请求,对SEO不利,前后台都要写逻辑控制,而且无法复用前后台的代码,存在一定程度上的重复开发。URL的设计要严重依赖配合后端,无法自主决定。

基于Nodejs的全栈时代

  随着 Node.js 的兴起,JavaScript 开始有能力运行在服务端。这也带来了全新的架构:

  这种架构下,存在两个UI Layer层,即他们都负责前台的工作:

    基于浏览器的UI layer处理浏览器层面的展示逻辑,通过CSS控制样式,js添加交互功能,HTML 的生成也可以放在这层。

    基于Nodejs的UI layer处理路由,模板,获取数据,cookie等。通过路由,前端终于可以自主把控 URL Design,这样无论是单页面应用还是多页面应用,前端都可以自由调控。

    这样一来,后端终于可以摆脱对展现的强关注,转而可以专心于业务逻辑层的开发。此时,web server上也是javascript代码,所以一定程度上“前后台”可以复用了,对于需要SEO的场景我们可以在服务端上进行渲染。

    这样基本解决了MV*时代的一些弊病。

-------------------------------讲了这么多,我们看看淘宝到底是怎么利用Nodejs实现前后端分离的----------------------------

借一张网友的图:

看看网友的分析:

  1. 最上端是服务端,就是我们常说的后端。后端对于我们来说,就是一个接口的集合,服务端提供各种各样的接口供我们使用。因为有Node层,也不用局限是什么形式的服务。对于后端开发来说,他们只用关心业务代码的接口实现。
  2. 服务端下面是Node应用。
  3. Node应用中有一层Model Proxy与服务端进行通讯。这一层主要目前是抹平我们对不同接口的调用方式,封装一些view层需要的Model。
  4. Node层还能轻松实现原来vmcommon,tms(引用淘宝内容管理系统)等需求。
  5. Node层要使用什么框架由开发者自己决定。不过推荐使用express+xTemplate的组合,xTemplate能做到前后端公用。
  6. 怎么用Node大家自己决定,但是令人兴奋的是,我们终于可以使用Node轻松实现我们想要的输出方式:JSON/JSONP/RESTful/HTML/BigPipe/Comet/Socket/同步、异步,想怎么整就怎么整,完全根据你的场景决定。
  7. 浏览器层在我们这个架构中没有变化,也不希望因为引入Node改变你以前在浏览器中开发的认知。
  8. 引入Node,只是把本该就前端控制的部分交由前端掌控。

  

  然后给了一个淘宝应用的例子:

  淘宝宝贝详情页静态化之后,还是有不少需要实时获取的信息,比如物流、促销等等,因为这些信息在不同业务系统中,所以需要前端发送5,6个异步请求来回填这些内容。
  有了NodeJS之后,前端可以在NodeJS中去代理这5个异步请求,还能很容易的做Bigpipe,这块的优化能让整个渲染效率提升很多。
  可能在PC上你觉得发5,6个异步请求也没什么,但是在无线端,在客户手机上建立一个HTTP请求开销很大,有了这个优化,性能一下提升好几倍。

  

----------最后我们总结一下-------------------

前后端分离的目的:

  前端:负责View和Controller层。更有甚者,引入Nodejs直接请求服务端,绕过后端数据处理。

  后端:负责Model层,业务处理/数据等。

前后端分离的意义:

  技术上,分工更专业

  业务上,沟通更便利

参考文献:

http://blog.sina.com.cn/s/blog_15ac991410102wtz7.html  设计和编程并走

http://blog.jobbole.com/65509/  lifesinger (@玉伯也叫射雕)

实现真正意义上的前后端分离------由淘宝引入nodejs引发的思考的更多相关文章

  1. 在centos7.6上部署前后端分离项目Nginx反向代理vue.js2.6+Tornado5.1.1,使用supervisor统一管理服务

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_102 这一次使用vue.js+tornado的组合来部署前后端分离的web项目,vue.js不用说了,前端当红炸子鸡,泛用性非常广 ...

  2. 服务器上详细前后端分离项目搭建(springboot+vue)

    介绍:本文用的经典的前后端分离开源项目ruoyi Gitee链接地址:https://gitee.com/y_project/RuoYi 一.拉取项目: 利用Git把项目拉取到本地,也可以直接利用id ...

  3. 利用gulp解决前后端分离的header/footer引入问题

    在我们进行前后端完全分离的时候,有一个问题一直是挺头疼的,那就是公共header和footer的引入.在传统利用后端渲染的情况下,我们可以把header.footer写成两个单独的模板,然后用后端语言 ...

  4. Django+vue在腾讯云上搭建前后端分离项目

    最近打算用Django+vue搭建一个个人主站,在此记录一下搭建项目的整个过程. 一 开发环境: 腾讯云Centos     7 Python                3.7 Django    ...

  5. 前后端分离之 跨域和JWT

    书接上回:https://www.cnblogs.com/yangyuanhu/p/12081525.html 前后端分离案例 现在把自己当成是前端,要开发一个前后分离的简单页面,用于展示学生信息列表 ...

  6. 浅谈Web前后端分离的意义

    自然是有很大意义的.下面我可能说的比较多--方便题主能够更全面的了解为什么说是有有意义的.另外,本文是以Java的角度谈前后端分离.放心,大家一定会有种是我了,没错,的感觉. 一.先来明晰下概念 前后 ...

  7. 前后端分离跨服务器文件上传-Java SpringMVC版

    近来工作上不上特别忙,加上对后台java了解一点,所以就抽时间,写了一个java版本的前后端分离的跨服务器文件上传功能,包括前后端代码. 一.Tomcat服务器部分 1.Tomcat服务器 单独复制一 ...

  8. Ueditor 前后端分离实现文件上传到独立服务器

    关于Ueditor 前后端分离实现文件上传到独立服务器,在网上搜索确实遇到大坑,不过还好遇到了 虚若影 最终实现了,在此感谢!虚若影的原文博客网址:http://www.cnblogs.com/hpn ...

  9. UEditor实现前后端分离时单图上传

    首先,需要下载部署ueditor相关代码,可以参考一篇简单的博客,这里不再赘述: 环境搭建好后,我们先简单使用一下,启动http://web.yucong.com:8080/ueditor/index ...

随机推荐

  1. node工具之pm2

    pm2 PM2是带有内置负载平衡器的Node.js应用程序的生产过程管理器.它使您可以使应用程序永远保持活动状态,无需停机即可重新加载它们,并简化常见的系统管理任务. 安装 npm install p ...

  2. WPF ListView多行显示

    //前台 <ListView Margin="14,152,12,74" Name="lvList" SelectionMode="Multip ...

  3. 前端页面多级联动传输数据类型问题(数组or字符串)后端处理

    在最近的工作中,遇到一个问题,个人所做的简历模块中有两个字段,分别是个人信息中的户口所在地和现居住城市. 前端界面中这两个选项框是用到了二级和三级联动,在向后端传输时希望可以通过数组类型进行传输,例如 ...

  4. CF407D Largest Submatrix 3

    cf luogu 被自己菜到自闭了/kk 既然是子矩阵,那么惯用套路为枚举矩阵上下边界,然后\(O(n)\)扫描求解.这题里要从左往右枚举右端点,然后看左端点最多能放到哪,那就对于每个数求出在上下边界 ...

  5. ABAP常用函数归纳

    转至:http://blog.csdn.net/forever_crazy/article/details/17707745 获取当前逻辑系统标识:OWN_LOGICAL_SYSTEM_GET 一.日 ...

  6. requests:用于发送http请求,专为人类设计

    介绍 requests模块是一个专门用来发送http请求的模块 如何发送请求 import requests """ 使用requests模块发送请求非常简单 首先请求有 ...

  7. Linux硬件访问技术

    在Linux系统中,无论是内核程序还是应用程序,都只能使用虚拟地址,而芯片手册中给出的硬件寄存器地址或者RAM地址则是物理地址,无法直接使用,因此,我们读写寄存器的第1步就是将将它的物理地址映射为虚拟 ...

  8. Systemctl和service、chkconfig命令的关系

      systemctl命令:是一个systemd工具,主要负责控制systemd系统和服务管理器. service命令:可以启动.停止.重新启动和关闭系统服务,还可以显示所有系统服务的当前状态. ch ...

  9. Jmeter 常见逻辑控制器详解

    简介 Jmeter有很多逻辑控制器,可以控制请求的执行顺序和执行逻辑,本文就Jmeter常见的逻辑控制器做一个详细的描述,并通过示例让大家了解逻辑控制器的作用.   代码的逻辑分支通常有: 条件判断I ...

  10. python-1.Centos7安装Python3.6和Scrapy的方法

    由于centos7原本就安装了Python2,而且这个Python2不能被删除,因为有很多系统命令,比如yum都要用到 [root@iZm5efjrz9szlsq1a0ai3gZ ~]# python ...