前言
只有光头才能变强。
文本已收录至我的 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 不可能写后台怎么办?》
有兴趣的小伙伴可以去了解一下,大多数内容还是挺通俗易懂的:
- https://www.zhihu.com/question/327657434/answer/704249816
我在下载 Node.js
的时候,发现其简介十分 简洁:
Node.js® is a JavaScript runtime built on Chrome’s V8 JavaScript engine.
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.
V8 是 Google 的开源高性能 JavaScript 和 WebAssembly 引擎,用 C ++ 编写。它用于 Chrome 和 Node.js 等。
看了介绍,一脸懵逼,这是啥玩意啊。下面我来解释一下
2.1 V8 引擎是什么?
众所周知,JavaScript 是 解析型 语言,我们写好的 JavaScript 代码会由 JavaScript 引擎去解析,而 V8 是 JavaScript 引擎的一种。
- 在传统意义上,我们会认为解析器是逐条解析(一边执行一边解析),但为了提高 JavaScript 的解析速度(相当于提高用户体验),在解析的时候做了点“手脚”。
- V8 引擎 :为了提高解析的性能,引入了一些“后端”的技术(不过他本来就由 C ++ 编写的)。它是先将 JavaScript 源代码转成抽象语法树,然后再将抽象语法树生成字节码。如果发现某个函数被多次调用或者是多次调用的循环体(热点代码),那就会将这部分的代码 编译优化 。说白了就是:对 热点代码 做编译,非热点代码直接解析。
总结:V8 引擎是 JavaScript 引擎的一种,这个引擎由 C ++ 来编写的,性能很不错。
参考资料:
- https://zhuanlan.zhihu.com/p/27628685
- https://zhuanlan.zhihu.com/p/73768338
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 的一个子类)
- JSP 本质上还是一个 Servlet,只不过看起来像
-
再后来,学到了 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):
- https://zhuanlan.zhihu.com/p/24357770
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
归属在后端还是前端?
看得不过瘾?推荐一下我认为不错的文章和资料:
- https://segmentfault.com/a/1190000009329474
- https://www.zhihu.com/question/267014376
- https://cnodejs.org/topic/565ebb193cda7a91276ff887
- https://github.com/yalishizhude/front-back-separation
乐于输出 干货 的 Java 技术公众号:Java3y。公众号内 有 200 多篇原创 技术文章、海量视频资源、精美脑图,关注即可获取!
觉得我的文章写得不错,点 赞!