前言
只有光头才能变强.
文本已收录至我的 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 https://v8.dev/ .
Node.JS® 是一个基于 Chrome V8 引擎 https://v8.dev/ 的 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 的一个子类)
再后来, 学到了 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
乐于输出干货的 Java 技术公众号: Java3y. 公众号内有 200 多篇原创技术文章, 海量视频资源, 精美脑图, 关注即可获取!
觉得我的文章写得不错, 点赞!
来源: https://www.cnblogs.com/Java3y/p/11320606.html