详解从NodeJS搭建中间层再谈前后端分离


Posted in NodeJs onNovember 13, 2018

之前在知道创宇的项目中有用到过nodejs作中间层,当时还不太理解其背后真正的原因;后来在和一位学长交谈的过程中,也了解到蚂蚁金服也在使用类似的方法,使用nodejs作为中间层去请求真实后台的数据;之后人到北京,也见到现在的公司也在往nodejs后端方向靠拢。随着知识的增加,加之自己查阅资料,慢慢总结出了一些原理。

为什么要前后端分离

1、开发效率高
前端开发人员不用苦苦地配置各种后端环境,安装各种莫名的插件,摆脱对后端开发环境的依赖,一门心思写前端代码就好,后端开发人员也不用时不时的跑去帮着前端配环境。

2、职责清晰,找bug方便
以前有了bug,前端推后端,后端推前端,不知道该谁去该,前后端分离,是谁的问题就该谁去处理,处理问题方便很多,后期代码重构方便,做到了高可维护性。

从做微信小程序引发的思考

最近出于爱好,写了个音乐播放器的微信小程序(原本想用vue写的,后来因为公司业务原因,年后可能去做微信小程序,所以就换了前端技术栈),源码在我的GitHub上: wx-audio 。

思考:后端出于性能和别的原因,提供的接口所返回的数据格式也许不太适合前端直接使用,前端所需的排序功能、筛选功能,以及到了视图层的页面展现,也许都需要对接口所提供的数据进行二次处理。这些处理虽可以放在前端来进行,但也许数据量一大便会浪费浏览器性能。因而现今,增加node端便是一种良好的解决方案。

在我的微信小程序demo的server端代码中,我通过http模块对真实后台(网易云音乐API)发起http请求,然后通过express模块搭建后端服务。

发起请求:

// http.js
var formatURL = require('./formatURL.js');
var http = require('http');
const POSThttp = function(request){
 return new Promise((resolve, reject) => {
  let body = '';
  // http模块拿到真实后台api的数据
  http.get(formatURL(request.body.musicname), function(res){
   res.on('data', (data) => {
    body += data;
   }).on('end', () => {
    // 格式化
    const {
     name,
     audio: musicUrl,
     page,
     album: {
      name: musicName,
      picUrl,
     },
     artists: [{
      name: singer,
     }],
    } = JSON.parse(body).result.songs[0];
    const reply = {
     name,
     picUrl,
     musicUrl,
     page,
     singer,
    };
    resolve(reply);
   });
  });
 });
};
module.exports = POSThttp;

得到数据传回前端:

var express = require('express');
var POSThttp = require('./POSThttp.js');
var bodyParser = require('body-parser');
// 使用body-parser解析post请求的参数,如果没有,req.body为undefined。
var app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
 extended: true
}));
app.post('/', (req, res) => {
 POSThttp(req).then((data) => {
  res.send(data);
 }).catch((err) => {
  res.send(err);
 });
});
app.listen(3000, () => {
 console.log('open wx-audio server successful!')
});

这几十行代码也就实现了一个简单的中间层的demo,并做到了在中间层格式化参数,便于前端进行使用的过程。

为什么需要中间层?

其实这个问题,我认为跟面试常考的题:“为什么需要前后端分离?”是类似的,其原因可以归纳为以下几点:

现今网站存在问题

之前有向一位在百度有多年工作经验的老前辈交谈这类问题,我所提到的搜狐公司代码冗余、前后端耦合的问题,他是这么回答并且给予我这样的建议:

其实,提炼出来,现今大公司的老项目(包括百度、搜狐等公司所采用的后端渲染等),或多或少都会存在这样的一些 问题 :

  • 前端代码越来越复杂
  • 前后端依旧高度耦合
  • 无法良好的支持跨终端

前辈们提出的解决方案

参考 淘宝前后端分离解决方案

  • 前端代码越来越复杂,我们希望尽可能地减少工作量,开始使用类似MV*的分层结构,使前端后分离成为必要。
  • 前端需要处理更多的工作,希望有权操控View,Router(如:SPA的尝试)
  • 各种终端设备的兴起,需要我们把页面适配到更多的地方。

开始:我们所尝试的CLIENT-SIDE MV* 框架,后端暴露数据接口、处理业务逻辑,前端接收数据、处理渲染逻辑。

关于MVC的定义:

MVC是一种设计模式,它将应用划分为3个部分:数据(模型)、展现层(视图)和用户交互(控制器)。换句话说,一个事件的发生是这样的过程:

1. 用户和应用产生交互。

2. 控制器的事件处理器被触发。

3. 控制器从模型中请求数据,并将其交给视图。

4. 视图将数据呈现给用户。

我们不用类库或框架就可以实现这种MVC架构模式。关键是要将MVC的每部分按照职责进行划分,将代码清晰地分割为若干部分,并保持良好的解耦。这样可以对每个部分进行独立开发、测试和维护。

如:Backbone, EmberJS, KnockoutJS, AngularJS等框架。

但这样的方式仍旧存在问题:

各层职责重叠

  • Client-side Model 是 Server-side Model 的加工
  • Client-side View 跟 Server-side是 不同层次的东西
  • Client-side的Controller 跟 Sever-side的Controller 各搞各的
  • Client-side的Route 但是 Server-side 可能没有

性能问题

  • 渲染,取值都在客户端进行,有性能的问题
  • 需要等待资源到齐才能进行,会有短暂白屏与闪动
  • 在移动设备低速网路的体验奇差无比

重用问题

  • 模版无法重用,造成维护上的麻烦与不一致
  • 逻辑无法重用,前端的校验后端仍须在做一次
  • 路由无法重用,前端的路由在后端未必存在

跨终端问题

  • 业务太靠前,导致不同端重复实现
  • 逻辑太靠前,造成维护上的不易

渲染都在客户端,模版无法重用,SEO实现 麻烦

NodeJS作为中间层的全栈开发方案

有了NodeJS之后,前端可以更加专注于视图层,而让更多的数据逻辑放在Node层处理。

我们使用Node层:

  • 转发数据,串接服务
  • 路由设计,控制逻辑
  • 渲染页面,体验优化
  • 中间层带来的性能问题,在异步ajax转成同步渲染过程中得到平衡
  • 更多的可能

其实更为重要的是,对于前端来说,NodeJS的学习成本是相当低的:我们无需学习一门新的语言,就能做到以前开发帮我们做的事情,一切都显得那么自然。

技术在不断变化中,唯有跟上技术革新的浪潮,才能不被时代所淘汰,不管是人还是企业。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

NodeJs 相关文章推荐
nodejs 提示‘xxx’ 不是内部或外部命令解决方法
Nov 20 NodeJs
轻松创建nodejs服务器(3):代码模块化
Dec 18 NodeJs
nodejs开发——express路由与中间件
Mar 24 NodeJs
初识NodeJS服务端开发入门(Express+MySQL)
Apr 07 NodeJs
nodejs 终端打印进度条实例代码
Apr 22 NodeJs
Nodejs实现多房间简易聊天室功能
Jun 20 NodeJs
Windows下快速搭建NodeJS本地服务器的步骤
Aug 09 NodeJs
NodeJS 实现多语言的示例代码
Sep 11 NodeJs
NodeJS服务器实现gzip压缩的示例代码
Oct 12 NodeJs
nodejs 使用http进行post或get请求的实例(携带cookie)
Jan 03 NodeJs
使用nodeJS中的fs模块对文件及目录进行读写,删除,追加,等操作详解
Feb 06 NodeJs
node快速搭建后台的实现步骤
Feb 18 NodeJs
手把手教你如何使用nodejs编写cli命令行
Nov 05 #NodeJs
基于nodejs的雪碧图制作工具的示例代码
Nov 05 #NodeJs
nodejs遍历文件夹下并操作HTML/CSS/JS/PNG/JPG的方法
Nov 01 #NodeJs
nodejs中函数的调用实例详解
Oct 31 #NodeJs
NodeJS 将文件夹按照存放路径变成一个对应的JSON的方法
Oct 17 #NodeJs
Nodejs实现多文件夹文件同步
Oct 17 #NodeJs
深入理解NodeJS 多进程和集群
Oct 17 #NodeJs
You might like
我的论坛源代码(一)
2006/10/09 PHP
PHP 透明水印生成代码
2012/08/27 PHP
PHP+MySQL统计该库中每个表的记录数并按递减顺序排列的方法
2016/02/15 PHP
windows7配置Nginx+php+mysql的详细教程
2016/09/04 PHP
php大小写转换函数(strtolower、strtoupper)用法介绍
2017/11/17 PHP
PHP面向对象程序设计模拟一般面向对象语言中的方法重载(overload)示例
2019/06/13 PHP
tp5.1 框架join方法用法实例分析
2020/05/26 PHP
javascript 中对象的继承〔转贴〕
2007/01/22 Javascript
javascript实现按回车键切换焦点
2015/02/09 Javascript
javascript实现当前页导航激活的方法
2015/02/27 Javascript
实例详解jQuery Mockjax 插件模拟 Ajax 请求
2016/01/12 Javascript
Vue.js开发环境搭建
2016/11/10 Javascript
详解React Native网络请求fetch简单封装
2017/08/10 Javascript
微信小程序实现自定义modal弹窗封装的方法
2018/06/15 Javascript
Vue 页面状态保持页面间数据传输的一种方法(推荐)
2018/11/01 Javascript
基于jquery实现的tab选项卡功能示例【附源码下载】
2019/06/10 jQuery
vue filter 完美时间日期格式的代码
2019/08/14 Javascript
JavaScript多种滤镜算法实现代码实例
2019/12/10 Javascript
[05:59]2018DOTA2国际邀请赛寻真——只为胜利的Secret
2018/08/13 DOTA
python django集成cas验证系统
2014/07/14 Python
Python中用于计算对数的log()方法
2015/05/15 Python
Python编程之多态用法实例详解
2015/05/19 Python
python在控制台输出进度条的方法
2015/06/20 Python
Tensorflow 利用tf.contrib.learn建立输入函数的方法
2018/02/08 Python
python list是否包含另一个list所有元素的实例
2018/05/04 Python
Python3.6.x中内置函数总结及讲解
2019/02/22 Python
python 比较字典value的最大值的几种方法
2020/04/17 Python
香港士多网上超级市场:Ztore
2021/01/09 全球购物
Windows和Linux动态库应用异同
2016/04/17 面试题
大学生学习自我评价
2014/01/13 职场文书
简历中的自我评价范文
2014/02/05 职场文书
文明村创建实施方案
2014/03/27 职场文书
2019西餐厅创业计划书范文!
2019/07/12 职场文书
导游词之凤凰古城
2019/10/22 职场文书
spring cloud 配置中心客户端启动遇到的问题
2021/09/25 Java/Android
Java9新特性对HTTP2协议支持与非阻塞HTTP API
2022/03/16 Java/Android