立即注册找回密码

QQ登录

只需一步,快速开始

微信登录

微信扫一扫,快速登录

手机动态码快速登录

手机号快速注册登录

搜索

图文播报

查看: 261|回复: 5

[讨论] 如何正确理解前后端分离?

[复制链接]
发表于 2025-5-30 21:11 | 显示全部楼层 |阅读模式

登陆有奖并可浏览互动!

您需要 登录 才可以下载或查看,没有账号?立即注册 微信登录 手机动态码快速登录

×
假设一个web项目包含如下三部分:1.前台页面(游客,会员等访问的页面);2.后台页面(管理员访问的页面);3.后台service
关于前后端分离,是将前台页面和后台页面都剥离出来通过api访问后台,后台service只提供restful api即可;还是说只将前台页面剥离出来通过restful api与后台交互,而后台页面还是与后台service集成在一起?
看了几个开源项目都只是将前端页面剥离,独立开发部署,而后台页面仍然与后台service集成在一起,望哪位明白人指点一下!
原文地址:https://www.zhihu.com/question/267014376
楼主热帖
回复

使用道具 举报

发表于 2025-5-30 21:12 | 显示全部楼层
之前写过一篇前后端分离的笔记(入门级别的),希望对题主有帮助。收藏等于白嫖,点赞才是真情!

前言

只有光头才能变强。
文本已收录至我的GitHub仓库,欢迎Star:https://github.com/ZhongFuCheng3y/3y
前后端分离这个词相信大家都听过,不知道大家是怎么理解的呢。前阵子看项目的时候,有一段实现硬是没看懂,下面来给大家说一下一段愚蠢的经历哈。
(我没正正式式写过前端,所以如果文章有错的地方希望可以在评论区友善交流~)
一、交代背景

我一直都知道我现在的这个系统是前后端分离的,我的接口只会返回JSON出去,但我不曾关心前端是怎么处理我的JSON数据的(以及他是怎么跑通和运行的)
在某一天,我在查接口的时候,习惯F12,想直接看一下这个请求返回的JSON数据是什么。但是一看,在network返回的是html格式:




于是,我就很好奇啊,就看一下这个接口是不是我想象中的那个。于是就去找我的接口,看一下是不是真的返回JSON(我还专门Debug了一下,看看是不是真请求到这个接口上了):




得出的结果是:我的接口的确是返回JSON数据,浏览器的reponse返回的的确是HTML格式
于是,我就去找我前端的小伙伴,去问了一下这是怎么搞的。他回复我说:“在浏览器看到返回的是页面,那肯定是你们后端干的呀”
我说:“没有啊,我Java接口返回的是JSON数据啊,是不是中途你们用node做了些处理啊?”(我之前听过Node.js,但仅仅是听过)
他说:“Node.js也是你们后端的啊。”
我一听,啊?Node.js不是属于前端的吗?
二、初识Node.js

在遇到这个事情之前,其实我在知乎已经看了一个帖子,话题名是这个《毕设答辩,老师说node不可能写后台怎么办?》
有兴趣的小伙伴可以去了解一下,大多数内容还是挺通俗易懂的:
我在下载Node.js的时候,发现其简介十分简洁
Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine.
<hr/>Node.js® 是一个基于 Chrome V8 引擎 的 JavaScript 运行时。

然后点进去Chrome V8引擎,再看了一下介绍:
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++. It is used in Chrome and in Node.js, among others.
<hr/>V8是Google的开源高性能JavaScript和WebAssembly引擎,用C ++编写。它用于Chrome和Node.js等。

看了介绍,一脸懵逼,这是啥玩意啊。下面我来解释一下
2.1 V8引擎是什么?

众所周知,JavaScript是解析型语言,我们写好的JavaScript代码会由JavaScript引擎去解析,而V8是JavaScript引擎的一种。

  • 在传统意义上,我们会认为解析器是逐条解析(一边执行一边解析),但为了提高JavaScript的解析速度(相当于提高用户体验),在解析的时候做了点“手脚”。
  • V8引擎:为了提高解析的性能,引入了一些“后端”的技术(不过他本来就由C++编写的)。它是先将JavaScript源代码转成抽象语法树,然后再将抽象语法树生成字节码。如果发现某个函数被多次调用或者是多次调用的循环体(热点代码),那就会将这部分的代码编译优化。说白了就是:对热点代码做编译,非热点代码直接解析




总结:V8引擎是JavaScript引擎的一种,这个引擎由C++来编写的,性能很不错。
参考资料:
2.2回到Node.js

浏览器为了安全,没有为JavaScript提供一套IO环境,而一门后端语言是肯定能进行网络通信、文件读写(IO)的。
后来,有牛逼的人把V8引擎搬到了服务端上,在V8引擎的基础上加了网络通信、IO、HTTP等服务端的函数。取了一个名字叫:Node.js

  • 比如通过libuv库来进行文件读取,以及建立TCP/UDP连接。通过xxx库解析HTTP请求和响应....这些库都是由C/C++来编写的。




所以,Node.js是运行在服务端的,只不过在基础语言是JavaScript。
三、前后端分离入门

回顾一下自己学JavaWeb的历程:

  • 刚学Servlet的时候,会在response对象上写一些HTML代码输出到浏览器看效果
  • 后来,学习到JSP了,就纯粹用Servlet做控制,JSP做视图。
  • JSP本质上还是一个Servlet,只不过看起来像HTML文件,在编译的时候还是会变成一个HttpJspPage类(该类是HttpServlet的一个子类)
  • 再后来,学到了AJAX技术,发现我们完全可以通过AJAX来进行交互。AJAX请求Servlet,Servlet返回JSON数据回去,AJAX拿到Servlet返回的数据进行解析和处理。这里压根就不需要JSP了(纯HTML+AJAX),这算是前后端分离的一种了
  • 在开发上体验:如果完全使用HTML+AJAX的话,会发现其实需要写非常非常多的JavaScript代码,而且这些JavaScript代码都不好复用。
  • 在部署上,还是跟Java一起部署(放在resource下),没有将前端单独部署。
  • 再后来,学到了一些在常用的模板引擎(比如freemarker),其实用起来跟JSP没多大的区别,只不过性能要比JSP好不少。
  • ...流下不学无术的泪水
目前我了解到的前后端分离,首先部署是分离的(至少不会跟Java绑定在一起部署):




Java接口只返回JSON数据:




关于前端这几大框架:angular/vue/react这几个我都是没有写过的,所以也就不多BB了。我一直想知道的是:前框框架和node是啥关系。问了一下前端的小伙伴,他回复是大致这样的:
前端现在是讲究工程化的,工程化用到了node而已(就是打包编译那些会用到,项目里面真正跑起来的话是没有这些东西的)
-----------以下引用摘录:
Webpack、Less、Sass、Gulp、Bower以及这些工具的插件都是Node上开发的---@知乎陈龙
举个例子:随着发展,前端的JavaScript需要依赖的包也非常复杂,类比于Java我们会有Maven,而前端现在有npm (包管理

  • 而npm是随同Node.js一起安装的。所以前端(vue/angular/react)在开发环境下都是离不开Node.js的(编译、打包等等)
参考资料(为什么要使用 npm):
3.1 方式一(Nginx+Server)

OK,现在假设我们用前端(vue/angular/react)开发完,开发环境下将JavaScript编译/打包完,那我们能得到纯静态的文件。我们可以直接将纯静态文件放到Nginx(CDN)等等地方【只要能够响应HTTP请求就行】。
如果请求是调用后端服务,则经过Nginx转发到后端服务器,完成响应后经Nginx返回到浏览器。
3.2 方式二(加入Node.js)

在前边的基础上加入Node.js,至于为啥要Node.js,一个重要的原因就是:加快首屏渲染速度,解决SEO问题
加入Node.js,此时的请求流程应该是这样的:




浏览器发起的请求经过前端机的Nginx进行分发.
URL请求统一分发到Node Server,在Node Server中根据请求类型从后端服务器上通过RPC服务请求页面的模板数据,然后进行页面的组装和渲染;
API请求则直接转发到后端服务器,完成响应。
最后

好的,现在问题来了:你是觉得Node.js归属在后端还是前端?

看得不过瘾?推荐一下我认为不错的文章和资料:
乐于输出干货的Java技术公众号:Java3y。公众号内有200多篇原创技术文章、海量视频资源、精美脑图,关注即可获取!
关注我的GitHub,干货不断:https://github.com/ZhongFuCheng3y/3y
回复 支持 反对

使用道具 举报

发表于 2025-5-30 21:12 | 显示全部楼层
前后端分离核心是职责分离,让工程师各司其职,让程序通过合理的解耦,实现性能和效率的提升。

至于分离形式其实并不重要,到底是restful,还是html片段,抑或者其他数据传输方案,只要能保障数据一致准确,不会引起问题即可。

问题中的矛盾点在于迷惑是否要将toB甚至可以说是内部的管理后台一并进行前后端分离。

我的看法是,谁维护,按谁的标准实施。

如果是后端维护,你哐哐一顿改,后端接不住;如果是你维护,按照他的模式开发部署,前端效率又提不上去。

至于最佳实践,从来不止一个套路。
回复 支持 反对

使用道具 举报

发表于 2025-5-30 21:13 | 显示全部楼层
嗯。再来说一下,为什么要做前后端分离。
前端后端有两种协作方式,一种可以称之为是服务器端渲染,一种是叫做前后端分离。
这两种方式的差别是什么呢?

服务器端渲染的方式,是指在服务器端就将网页直接生成,浏览器这里拿到的是一整个网页,CSS和JS的部分是在浏览器端执行的,而网页的内容部分,也就是数据,是由服务器端生成的。
这叫做服务器端渲染。

至于你是用NodeJS,还是用PHP,还是Python,还是Java,还是NodeJS+Java,都不重要。
这是我一直都觉得,很多概念在混淆的原因,很多人都觉得说到前后端分离,就是JS和Java的分离,只要我用了JS,Java提供API,就是前后端分离了。

是这样么?不是的。
只要你的Html网页的内容是在服务器端生成的,这就是服务器端渲染的方式。你用Openresty+lua没问题。
只要你的网页是在浏览器端,内容是通过接口从后端拿到的纯数据,这就是前后端分离。

第二种方式就是,前后端分离的方式,也是刚刚说到的。浏览器端先拿到Html,然后和后端通过Ajax接口获取,或者是通过其他接口获取,无所谓。

所以两种方式的区别关键,就在于是,Html是在哪儿生成的,浏览器和服务端传递的是什么。
在前后端分离的方式,浏览器和服务端传递的是数据,而在服务器端渲染的过程中,传递的是Html网页。

弄清楚这两点的差别,再来看两种方式的好坏。
1 数据量:前后端分离中传递数据,所以传输量会小。
                 服务器端渲染,会传输更大的数据,而且,会有很多内容是重复的。
2 体验:前后端多了一个渲染数据的过程,服务器端省去了这个过程。这也是一直被提到的首屏渲染的问题。

3 解耦:前后端分离中,传输的是数据,Model,数据怎么展示,全部交给前端来处理,后端只负责提供数据。
             服务器端渲染中,传输的是Html,后端传给前端的Model,通常是通过Hidden的Input来处理,或者是直接用模板技术生成(JSP,Velocity,freemak)等。
             数据和展现并未分离,在过去,这被称之为套页面。
4 控制:网页之间有各种跳转交互,在前后端分离中,跳转的页面控制,全部是由前端来决定。跟后端完全没有关系。在服务器端渲染的方式中,大部分是由后端来决定,少部分是由前端来决定。

5 SEO:前后端分离的方式,通常的载体是SPA,所以拿到的是没有数据的空壳子,很多搜索引擎,不支持SPA方式的SEO。
               而服务器端渲染的方式,因为生成的是网页,所以对SEO支持的很好。

               不要小巧这个环节,这是重多前台网站放弃使用前后端分离方式的重要原因。

好了,以上5点,足以让你对前后端分离和服务器渲染两种方式有一些直观的认知了。

再举个例子:
盒马生鲜提供两种方式,一种是前后端分离,一种是服务器端渲染。
前后端分离是哪种方式呢?就是外卖或者是直接买生鲜,自己回家去做。
服务器端渲染是哪种方式呢?就是直接在盒马鲜生自己加工,直接吃,或者是带回家吃。

这里的生鲜就是数据。
做出来的食物就是Html网页。

接着看在什么样的场景下,应该使用前后端分离,很简单。
“不需要SEO的场景下,都应该使用前后端分离”。

所以在后台管理中,没有任何理由不使用前后端分离,代指SPA。
而在前台页面中,要认真考虑,不支持SEO的代价,不止几百万。
前后需要用户登录的页面,往往是不需要有SEO的,这里也可以拆解出来。


再说一下,什么是动静分离。
之前跟人讨论的时候,有人说你不懂什么叫前后端分离,就算是服务器端渲染,也可以把CSS和JS从Java代码中剥离出来。

可是这更应该叫做动静分离,跟前后端分离是完全两个含义。
动静分离主要在于部署,静态代码部署不用重启,动态代码部署需要重启,很多时候我改一个样式,不想要重启服务,不想要重新打Tag。


所以,说到前后端分离,前后端只传递数据的方式,是彻底的改变,不是什么后端前端撕逼(所有管理能解决的问题都不是技术问题),也不是什么后端不想要给前后提供数据,就是单纯的这种方式更符合前后端交互的逻辑,后端本来就只应该关心数据,和Android和IOS的交互方式一样,根本不用关心数据怎么展示。

前端说到的前后端分离,在某种程度上,就是和Android和IOS看齐。

关键点弄明白了,其他的各种好处我可以随便扯了,比如说后端提供一套API,比如说,前端部署更方便,双方开发速度更快更高效,更适合做单元测试等等等。
而题主说到的后台没有拆分,很可能的原因就是“懒”。

很多时候,我知道怎么样做是对的,但是我就是懒,这是程序员的天性,特别是在一个人开发的时候。
回复 支持 反对

使用道具 举报

发表于 2025-5-30 21:14 | 显示全部楼层
现在大部分前端新人只写「前后端分离的代码」,所以很难理解前后端分离的边界在哪里。


其实判定很简单:如果前端和后端只通过简单的 API 文档就能进行数据交流,就说明他们的逻辑是分离的。我们可以称之为「前后端代码分离」。
如果除了 API 文档之外还需要各种其他的数据交流方式,比如后端把数据藏在一个 div 的属性里,那么就不是前后端分离的(因为这根本就不算是一个 API,只能算是一种「私下约定」,但是在实际工程中,总是会保留一两个这样的约定)。

这看起来是一句废话,但是很早之前的 Web 开发确实没有这个意识。导致页面代码杂乱,PHP 中有 JS,JSP 中有 JS,ASP 中有 JS,JS 中有 HTML,HTML 中有 CSS,HTML 中还有 JS,JS 中还有 CSS,CSS 中还有 JS(比如 IE 这个死浏览器)。代码一点也不「分离」。这种代码结构根本就没有 API 的概念,只有数据在各处流窜,极难维护。
为了鄙视这种代码,才有了前后端分离运动。

但是要注意:前后端分离不代表前后端代码是两个人写的,如果代码是两个人写的,那么就是前后端「分家」。如果代码是一个人写的,这个人也不叫做「全栈开发者」,应该叫做 「Web 开发者」,流行的叫法叫做「大前端」。
前后端人员「分家」必然导致前后端代码「分离」。

前后端分离的初衷是用「单一职责」原则把代码质量提上去,很难想象为什么之前的开发者连这么基本的原则都不知道吧,其实是因为以前没有 AJAX 这项技术,而且前端代码太少了,不值得花时间分离。后来突然 Web 大爆发,JS 代码和 CSS 代码从几百行跃升到几千行甚至几万行,不分一下就说不过去了。
前后端分离的一个不好的后果是让前后端人员分家(矫枉过正)。分家的问题我已经吐槽好几年了,不过之所以大公司喜欢让前后端人员分家,也是有一些客观原因的(康威定理)。(其实我很想说前后端分家就是错的,但是好像大家不喜欢听,那我就中庸一下吧)

为了防止有人扩大概念,我举一个明确的例子。
某大型 Web 应用,后端服务全部都是 Java 提供的 service(如数据服务)(并不是 HTTP service),业务部门的开发者需要

  • 使用 groovy 调用 Java 服务
  • 使用 groovy 响应前端的 AJAX 和 HTML 请求
  • 使用 JavaScript 做前端界面
这三件事都是一个开发者完成的,这就是一个 Web 开发者要做的事情。
他不需要自己去写 SQL 语句,也不需要自己去连接 Redis。
上面的 groovy 可以换成任何你喜欢的语言,比如 Python、Ruby 或者 JS,都一样。
这个时候如果你要问前后端分离在哪里,其实没有什么意义。因为既然前后端都是同一个人,其实不写文档也没事(当然还是写文档更好),如果你一定要他写文档,也是很简单事情,因为代码都是他写的嘛。而且他自己在前端调用 HTTP 服务的时候用的就是 AJAX + JSON 的方式,这很分离。
这么做的最大好处就是节省人力和减少沟通时的信息损失。另一个好处就是让你多学一门语言(我知道有些人认为多学一门语言是坏处),还有一个好处就是没有什么蛋疼的「前后端联调」了。

总之:

  • 前后端代码分离是百分百正确,而且是现在的主流,但是要不要分家(分成两个团队,一个前端,一个后端)则是值得商榷的。因为每次前后端撕逼和联调都是效率的瓶颈
  • 请区别对待前后端代码「分离」,和前后端人员「分家」。如果你司已经把前后端「分家」了,那么基本上前后端代码也是「分离」的。但是如果你司没有让前后端「分家」,那么前后端代码可能是「分离」的,也可能是「不分离」的,如何判定前文已经说了。
  • 前后端分家的对立面并不是全栈,而是 Web 开发。未来的趋势是大前端,也就是我上面说到的 groovy 的例子。
回复 支持 反对

使用道具 举报

发表于 2025-5-30 21:14 | 显示全部楼层
首先得理解为什么要前后端分离,即分离的目的是什么,或分离的优势是什么。那为什么之前又要做成不分离的呢?
============================================================
在早期(5~8年前)web开发中,由于js是一门非常弱工程化的语言所以js的用处往往是做点动画效果,简单的交互和ajax访问。而后端主要负责数据部分,然后以插标签的方式插入到页面。
这么做最大的问题,就是找谁做好?前端要懂后端,后端要懂前端,这样的人找起来比较麻烦。后端的人往往不想学或不屑于做前端,而前端又要懂得后台,并且配好开发环境才能开发,一旦后台换一个语言换一个框架就得重学,所以前端做插标签又累做的又不精。
从经验来看,这类事情最终还是很有可能落在后端的人头上。随着交互的复杂越来越大,这个问题越来越突出,模板引擎越写越复杂,后台做的不光光是插标签还有很多杂事,如果客户要改页面了,而此时前端已经不会改你的模板了,所以他们还要负责前端的擦屁股。然后他们就被迫变成了全栈工程师。并且全栈工程师的成本不低。
还有全后端分离会有一个重大的问题,就是搜索引擎爬虫爬不到关键信息(baidu不行,google可以)。
当时每个人都想做前后端分离,都在摸索。但是鉴于当时的技术水平,很难完美解决。这个问题也是5年前web研究的大方向,如何让网站开发更加工程化。有提出了很多框架,backbone,angular等,最初也没考虑那么多只是,只是觉得后端的模板已经满足不了那么大量的交互以及逻辑了,所以试着把原来应该插标签的东西放到js做。结果发现意外的好,这样根本不需要后台来插标签了嘛,全部ajax来取数据后通过angular的模板系统插进去,还有自带控制器来控制各种条件。所以以angular为代表的类前后端分离就开始行成意识形态。
同时,并且随着手机APP的流行,后台也非常不想单独为web版单独开发,所以只是提供了统一的接口,然后强迫前端去做前后端分离,这也是一个原因。
下面说句题外话:
如果做过桌面和APP的程序员会发现,html和js这个语言真tm弱工程化,怎么管理依赖?纯手动<script>哦对了还有css呢。大项目想想都累,而且文件又不适合写的太小,不然include几十个script,几十个css,小文件加载速度慢,而且为了有扩展性,几乎是不去管理依赖关系,一股脑的全include进来。那时候的解决方案是requirejs,什么CMD AMD标准。虽然一部分程度解决了前端的混乱程度。但是真正的出现重大转机是nodejs的崛起,随着nodejs的普及,人们想到,为何不把nodejs的语法运用到web开发中。这样开发前端就像开发手机APP或者桌面应用一样,依赖管理有了很好的解决,然后bang,这个世界变了,browserify/webpack,grunt/gulp,reactJS/angular2还有你们最爱的VUE,如雨后春笋版出现。引领了前端系统化,可工程化。

然后就出现了现在看到的景象。前端后端的分离有了充分且必要的条件甚至具备了SPA的条件。大家终于可以愉快的分离了。前端做前端的,后端关心好后端的逻辑,岂不美哉。
============================================================
最后回答你的问题
2种都可以。
第一种属于激进的人干的事情,但绝对是未来的方向。如果你现在才开始的项目一定要这么做。
第二种属于时代的眼泪,因为后台(运维平台),一般是全栈写的,他们主要方向在后台,对于变化如此迅速的前端世界还没做好准备。或者说他们没有非常强大的做分离的需求。因为运维平台,主要还是给自己人用的,好不好看不是重点,功能是重点。
不过我觉得,有时运维平台不做分离也是有优势的。比如我以前也做过一套框架(全栈),python+angular的。我写好一大堆前后台的bridge,我只要改改我的python代码就能更改管理平台的各种功能,完全不需要动前端的一行代码。全是python生成js给angular。虽然做成前后端分离也完全没问题。但是有些地方还真没python直接生成js 爽。
不过如果让我现在设计我也会想办法设计成第一种,因为现在前端到处是轮子,而我的年代到处要造轮子。

============================================================
出于工作经验,若有不对的地方希望批评。
最后希望有所帮助。
2018/2/11
回复 支持 反对

使用道具 举报

发表回复

您需要登录后才可以回帖 登录 | 立即注册 微信登录 手机动态码快速登录

本版积分规则

关闭

官方推荐 上一条 /3 下一条

快速回复 返回列表 客服中心 搜索 官方QQ群 洽谈合作
快速回复返回顶部 返回列表