express系列(1)概述
在 Node.js 出现之前,前后端的开发必须使用不同的语言进行。为此你需要学习多种的语言和框架。有了 Node.js 之后,你就可以使用一门语言在前后端开发中自由切换,这是最吸引人的地方。
什么是 Express ?
Express 是一个基于 Node.js 封装的上层服务框架,它提供了更简洁的 API 更实用的新功能。
它通过中间件和路由让程序的组织管理变的更加容易;它提供了丰富的 HTTP 工具;
Node.js 的功能
请求某个 API 接口,该函数就会把对应的 JSON 数据返回给客户端。
假设,现在需要服务器返回当前时间和时区信息给用户,那么该程序大致包括如下功能:
- 如果客户端发起主页请求,Web 应用将会返回一个包含所需信息的 HTML 。
- 如果客户端访问地址错误,Web 应用将会返回 HTTP 404 错误,并附带一段错误描述。
如果直接在 Node.js 之上构建该应用而不使用 Express 的话,那么完整流程图大抵如下:

在上述流程中,开发人员只需要关注圆圈部分内容处理。
用于处理浏览器请求的 JavaScript 函数叫做请求处理函数(request handler)。
它也仅仅是一个处理请求并作出响应的 JavaScript 函数,并无任何特殊之处。Node.js 的 HTTP 服务会接管其中的网络连接,所以你无需关注和处理复杂的网络协议内容。
从代码角度来说,该函数包含两个参数:
一个是网络请求 request 对象 ,另一个表示网络响应的 response 对象。
问题在于,Node.js 的 API 对开发者来说并不是非常友好。例如,如果我们想发送一个 JPEG 图片的话,可能需要至少 45 行代码才行。创建可复用 HTML 模版则更复杂。另外,Node.js 的 HTTP 模块虽然强大,但是仍然缺少一些实用特性。
Express 的出现就是为了解决这些问题,让你能够高效的使用 Node.js 来编写 Web 应用。
Express 给 Node.js 带来了什么?
从大的方面来说,Express 为 Node.js 的 HTTP 模块带来了两大特性:
- 通过提供大量易用接口,简化了程序的复杂度。例如上面放松 JPEG 图片问题,Express 可以将代码压缩带一行。
- 它允许对请求处理函数进行拆分,将其重构为很多负责特定请求的小型请求处理函数。这便于模块化和后期维护。
与上图相比,下图是 Express 处理请求的大致流程:

虽然,图看起来比前面复杂,但是实际开发却更简单,本质上它主要做了两件事:
- 与之前一个大型的 request 请求处理函数不同,这里使用大量小型处理函数。有些函数每次都会执行(例如,请求日志),而有些函数只在特定情形下才会触发(例如,404 错误)。Express 有很多使用的工具能够对这些处理函数进行区分。
- 请求处理函数中有两个参数:request 和 response。Node 的 HTTP 可以对其做些基本处理,例如:获取浏览器的 user-agent 。Express 则更为强大,你可以获取到访问者 IP 地址,以及解析优化过的 URL 请求对象。esponse 对象也同样得到了增强。通过类似 sendFile 这样的函数将文件传输代码压缩至一行。这极大的简化了处理函数的功能实现。
利用 Express 提供的简洁 API 接口,通过编写小型 request 请求处理函数,可以极大的压缩代码量提高开发效率。
Express 的核心
Express 非常简洁而且对 Node.js 的封装效果也非常棒,而这一切都源于框架中的四个设计。
中间件
正如之前提到的,原生的 Node.js 使用一个 request 处理函数应对所有请求并做出响应。
中间件可以处理各种任务,从记录请求到发送静态文件到设置 HTTP 头部。例如,应用中使用的第一个中间件功能可能就是记录服务器中每个请求的 logger-log。当日志记录完成后,它将继续执行调用链中的下一个中间件。而下一个中间件功能可能会去验证用户。如果权限不够,就会使用“未授权”进行提示。反之则继续执行下一个中间件。此时中间件功能可能会是渲染主页并结束响应。
下图演示了这两种情形:

在图中可以看出,记录日志的中间件位于第一个并且肯定会被执行。紧接着就是执行权限认证的中间件。如果用户权限满足的话就继续执行下一个中间件,否则就不再执行后续中间件。
中间件最大的特点就是其相对来说比较标准,这也意味着开发者可以通过为 Express 开发中间件来拓展其功能。同时,这也许意味着某些通用的中间件,很有可能已经有人开发过,例如:权限控制、cookies 和 sessions 的解析。
路由
相比中间件,Routing 显然更好。与中间价类似,路由对请求处理函数进行了拆分。不同的是,路由根据请求的 URL 和 HTTP 方法来决定处理方式的。
当用户使用 GET 去请求主页时,Express 会返回对应的主页内容。对留言板的请求的处理也是如此。如果用户通过 POST 方法在留言板页面中进行了留言操作的话,路由需要做出对应处理并刷新页面。
类似于中间件,上述路由的处理也是通过处理函数进行定义的。而不同的行为会调用不同的处理函数。
Express 中的中间件和路由相辅相成。例如:你可以一边记录请求日志,同时对主页路由做出响应。
子应用
Express 应用通常都很小,甚至可以是一个文件。随着应用规模的扩张,可能你会将其进行拆分为多个文件和文件夹。
通过实现正常规模的路由器子应用,可以将一个大型应用进行模块拆分。甚至你可以对某些子应用进行更细致的拆分。
例如,在应用中可能存在管理后台、单页应用、API 接口 等等几个子模块。这时,你就可以将这些子模块作为一个子应用来实现。详情如下:
01_05
当程序规模变大之后,该特性的优势将会逐步凸显出来。
易用的 API 函数
Express 由中间件和路由构成,在其中你需要编写大量的异步处理函数来实现相关功能。
为了使处理过程更加高效正确,Express 在原生的 Node.js 基础上进行了大量的封装。在压缩代码量提高效率的同时也降低了人为错误的概率。除了发送文件之外,Express 提供的 HTML 渲染功能也让原生 Node.js 望尘莫及。另外在请求解析方面,Express 也做了非常多的工作。
跟前面的特性不一样的是,在保持功能强大的同时这些易用的函数并不会对应用造成负面影响。
Express 的应用场景
理论上来说,Express 可以用来构建任何 Web 应用。对所有请求作出响应这件事上述提到的框架同样能够做到。
Express 相对较低的学习曲线使得前端开发者在几乎无需学习新内容的情况下搭建一个 SPA 服务。
Node.js 和 Express 的第三方模块
社区中存在大量可以在 Express 中使用的模块。有一些是 Express 独占的,这些模块与路由和中间件的特性高度兼容。其他的非独占模块也能提升 Express 应用的开发体验和程序性能。
另外,Express 本身并没有对数据库做支持。你可以通过文件、关系数据库、或者其他机制来实现数据保存。不过后面将会介绍在 Express 中如何通过 Mongoose 来调用 MongoDB 数据库。
需要注意的一点是:并不存在 Express 模块这一概念,所以第三方库都是 Node.js 模块。
Hello World
每次学习新内容的时候,绝大多数都是从 Hello World 开始。
那么现在我们来看看如何使用 Express 构建一个简单的 Hello World 工程。不要太关注代码的细节,后面将会进行详细介绍。代码如下:
var express = require("express"); #A
var app = express(); #B
app.get("/", function(request, response) { #C
response.send("Hello world!"); #C
}); #C
app.listen(3000, function() { #D
console.log("Express app started on port 3000."); #D
}); #D
A:导入 express 模块并新建变量。
B:创建 app 应用
C:设置访问 Root 路由,并将响应设置为 “Hello world!”。
D:设置程序监听的端口,并打赢服务启动成功的信息。
再次提醒一下,没有全部弄懂代码不要紧,后面会有更详细的讲解。
小结
本文主要介绍了:
- Node.js 可以编写 Web 应用,但是开发过程并不高效。而 Express 则优雅的解决了这些问题。
- Express 很小但是也非常灵活
- Express 有几个关键特性:
- 中间件将程序处理进行了拆分并且按照顺序链式执行。
- 路由同样对程序进行了拆分,按规则对不同的访问请求做出不同的响应。
- 子工程可以实现对大型 Express 的拆分,从而提高可读性方便后期维护。
- Express 中的代码大多请求处理函数的编写,而 Express 为此提供了大量易用 API 。
express系列(1)概述的更多相关文章
- 快速入门系列--MVC--01概述
虽然使用MVC已经不少年,相关技术的学习进行了多次,但是很多技术思路的理解其实都不够深入.其实就在MVC框架中有很多设计模式和设计思路的体现,例如DependencyResolver类就包含我们常见的 ...
- [2017-08-07]ABP系列——QuickStartA:概述、思想、入门和HelloWorld
唔,说好的文章,欠了好久,先水一篇. 本系列目录:Abp介绍和经验分享-目录 概述 先表个态:对绝大多数人来说,ABP是成熟的,足以用到生产环境的. 最适合的:业务非常复杂且不追求极致性能的(这里并不 ...
- Orleans 框架3.0 官方文档中文版系列一 —— 概述
关于这个翻译文档的一些说明: 之前逛博客园的时候,看见有个园友在自己的博客上介绍Orleans. 觉得Orleans 是个好东西. 当时心想:如果后面有业务需要的时候可以用用Orleans框架. 当真 ...
- C 标准库系列之概述
基本上很多编程语言都会提供针对语言本身的一系列的标准库或者包,当然C语言同样也有提供标准库,C语言的标准库是一系列的头文件的集合:如assert.h.ctype.h.errno.h.float.h.l ...
- zk系列-zookeeper概述
接触zk是2年前了,最近工作又比较依赖于zk,所以准备起个系列文章,系统的总结下. zookeeper是一个分布式的用于协调的服务,起源于Hadoop中的一个组件.分布式系统可以用zookeeper实 ...
- Dubbo系列_概述
一.本文目的 学习使用Dubbo也有一段时间了,准备写一个系列文章介绍Dubbo的相关知识和使用,供自己以后回顾和他人学习.有兴趣的同学可以加入群:74085440一起探讨 二.书写计 ...
- WCF基于Cookie回传的系列(概述)
1 WCF的基本知识(不作细述,园子里有很多的经典的文章系列) 2 WCF的执行过程 3 让服务通信像浏览器发送请求应答一样回传Cookie,并实现Cookie在不同的服务间共享 4 基于共享后的 ...
- nginx系列 2 概述
一. nginx功能概述 nginx 提供的基本功能服务归纳为:基本HTTP服务.高级HTTTP服务.邮件代理服务.TCP/UDP 代理服务等四大类. (1) Nginx提供基本HTTP服务,可以作为 ...
- asp.net core 系列 1 概述
一. 概述 ASP.NET Core 是一个跨平台的高性能开源框架,可以用来:建置 Web 应用程序和服务.IoT应用和移动后端.在 Windows macOS 和 Linux 上使用喜爱的开发工 ...
随机推荐
- hdu 3047 Zjnu Stadium(并查集)
题意: 300个座位构成一个圈. 有N个人要入座. 共有M个说明 :A B X ,代表B坐在A顺时针方向第X个座位上.如果这个说明和之前的起冲突,则它是无效的. 问总共有多少个无效的. 思路: 并查集 ...
- HTML基础-3
图像标签(<img>)和源属性(Src) 在 HTML 中,图像由 <img> 标签定义. <img> 是空标签,意思是说,它只包含属性,并且没有闭合标签. 要在页 ...
- pycharm的基本使用 、 Python的注释语法,变量,常量,垃圾回收机制,数据类型
1.文件路径要注意 我把文件放在了D盘,如下图:你们可以根据自身情况设置 2.python环境要选择本地下载好的 如下图: 点击本机存在的环境,如果提示NO interpr,就点击第二步 如果还是没有 ...
- java性能优化常用工具jps、jstat、jinfo
jps:虚拟机进程状况工具 jps可以用来查看虚拟机进程,基本等同于ps -ef|grep java #查看jps的使用文档 [root@localhost script]# jps -help us ...
- Cnetos 8 DNS解析慢
参考链接:https://blog.csdn.net/u014401141/article/details/105869242/ 修改 /etc/resolv.conf配置文件,最上方加入 optio ...
- NOIP模拟92&93(多校26&27)
前言 由于太菜了,多校26 只改出来了 T1 ,于是直接并在一起写啦~~~. T0 NOIP 2018 解题思路 第一次考场上面写三分,然而我并不知道三分无法处理不是严格单峰的情况,但凡有一个平台都不 ...
- redis批量操作
由于redis没有批量删除命令,所以借助xargs redis-cli -h 127.0.0.1 keys testdata_2018* |xargs redis-cli -h 127.0.0.1 d ...
- React-Router学习(基础路由与嵌套路由)
示例:基本路由 在这个例子中,我们有3个'Page'组件处理<Router>. 注意:而不是<a href="/">我们使用<Link to=&quo ...
- 手把手教你学Dapr - 9. 可观测性
目录 手把手教你学Dapr - 1. .Net开发者的大时代 手把手教你学Dapr - 2. 必须知道的概念 手把手教你学Dapr - 3. 使用Dapr运行第一个.Net程序 手把手教你学Dapr ...
- [hdu7023]Yet Another Matrix Problem
关于$f(x)$的条件,将$C=A\times B$代入,即$\sum_{i=1}^{n}\sum_{j=1}^{n}\sum_{k=1}^{r}A_{i,k}B_{k,j}=x$ 调换枚举顺序,即$ ...