在 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 处理请求的大致流程:

虽然,图看起来比前面复杂,但是实际开发却更简单,本质上它主要做了两件事:

  1. 与之前一个大型的 request 请求处理函数不同,这里使用大量小型处理函数。有些函数每次都会执行(例如,请求日志),而有些函数只在特定情形下才会触发(例如,404 错误)。Express 有很多使用的工具能够对这些处理函数进行区分。
  2. 请求处理函数中有两个参数: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 可以帮助你做到这一点,人们已经为这个技术栈拟好了名称:MEAN 。像 “LAMP” 代表 Linux、Apache、MySQL 和 PHP 一样,“MEAN” 表示 MongoDB、Express、Angular 和 Node.js。人们之所以对它喜爱有加是因为它是纯 JavaScript 技术栈。

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)概述的更多相关文章

  1. 快速入门系列--MVC--01概述

    虽然使用MVC已经不少年,相关技术的学习进行了多次,但是很多技术思路的理解其实都不够深入.其实就在MVC框架中有很多设计模式和设计思路的体现,例如DependencyResolver类就包含我们常见的 ...

  2. [2017-08-07]ABP系列——QuickStartA:概述、思想、入门和HelloWorld

    唔,说好的文章,欠了好久,先水一篇. 本系列目录:Abp介绍和经验分享-目录 概述 先表个态:对绝大多数人来说,ABP是成熟的,足以用到生产环境的. 最适合的:业务非常复杂且不追求极致性能的(这里并不 ...

  3. Orleans 框架3.0 官方文档中文版系列一 —— 概述

    关于这个翻译文档的一些说明: 之前逛博客园的时候,看见有个园友在自己的博客上介绍Orleans. 觉得Orleans 是个好东西. 当时心想:如果后面有业务需要的时候可以用用Orleans框架. 当真 ...

  4. C 标准库系列之概述

    基本上很多编程语言都会提供针对语言本身的一系列的标准库或者包,当然C语言同样也有提供标准库,C语言的标准库是一系列的头文件的集合:如assert.h.ctype.h.errno.h.float.h.l ...

  5. zk系列-zookeeper概述

    接触zk是2年前了,最近工作又比较依赖于zk,所以准备起个系列文章,系统的总结下. zookeeper是一个分布式的用于协调的服务,起源于Hadoop中的一个组件.分布式系统可以用zookeeper实 ...

  6. Dubbo系列_概述

    一.本文目的         学习使用Dubbo也有一段时间了,准备写一个系列文章介绍Dubbo的相关知识和使用,供自己以后回顾和他人学习.有兴趣的同学可以加入群:74085440一起探讨 二.书写计 ...

  7. WCF基于Cookie回传的系列(概述)

    1  WCF的基本知识(不作细述,园子里有很多的经典的文章系列) 2 WCF的执行过程 3 让服务通信像浏览器发送请求应答一样回传Cookie,并实现Cookie在不同的服务间共享 4  基于共享后的 ...

  8. nginx系列 2 概述

    一. nginx功能概述 nginx 提供的基本功能服务归纳为:基本HTTP服务.高级HTTTP服务.邮件代理服务.TCP/UDP 代理服务等四大类. (1) Nginx提供基本HTTP服务,可以作为 ...

  9. asp.net core 系列 1 概述

    一.   概述 ASP.NET Core 是一个跨平台的高性能开源框架,可以用来:建置 Web 应用程序和服务.IoT应用和移动后端.在 Windows macOS 和 Linux 上使用喜爱的开发工 ...

随机推荐

  1. 《手把手教你》系列技巧篇(三十八)-java+ selenium自动化测试-日历时间控件-下篇(详解教程)

    1.简介 理想很丰满现实很骨感,在应用selenium实现web自动化时,经常会遇到处理日期控件点击问题,手工很简单,可以一个个点击日期控件选择需要的日期,但自动化执行过程中,完全复制手工这样的操作就 ...

  2. APP自动化之Hybrid自动化解决方案(七)

    基于UIAutomator+ChromeDriver模式(UIAutomator安卓原生引擎) 原理:native(原生)部分使用UIAutomator,webview部分使用ChromeDriver ...

  3. MongoDB与MySQL效率对比

    本文主要通过批量与非批量对比操作的方式介绍MongoDB的bulkWrite()方法的使用.顺带与关系型数据库MySQL进行对比,比较这两种不同类型数据库的效率.如果只是想学习bulkWrite()的 ...

  4. Git 修改已提交的commit注释

    两种情况: 1.已经将代码push到远程仓库 2.还没将代码push到远程仓库,还在本地的仓库中 这两种情况下的修改大体相同,只是第一种情况最后会多一步 下面来说怎么修改 先搞清楚你要修改哪次的提交注 ...

  5. 2021广东省强网杯WriteUp

    个人赛 网络诈骗 参考 https://github.com/Heyxk/notes/issues/1 先把EnMicroMsg.db提出来 CompatibleInfo.cfg是0kb,用第一种方法 ...

  6. Apache Kyuubi 助力 CDH 解锁 Spark SQL

    Apache Kyuubi(Incubating)(下文简称Kyuubi)是⼀个构建在Spark SQL之上的企业级JDBC网关,兼容HiveServer2通信协议,提供高可用.多租户能力.Kyuub ...

  7. python实现拉普拉斯图像金字塔

    一,定义 二,代码: 要求:拉普拉斯金字塔时,图像大小必须是2的n次方*2的n次方,不然会报错 1 # -*- coding=GBK -*- 2 import cv2 as cv 3 4 5 #高斯金 ...

  8. P2066 机器分配 解析

    小日记: 1.今天新学的字体颜色,尽管不熟悉,但玩的666,卡星(开心) ╰( ̄▽ ̄)╮╰( ̄▽ ̄)╮╰( ̄▽ ̄)╮╰( ̄▽ ̄)╮╰( ̄▽ ̄)╮╰( ̄▽ ̄)╮ 2.今天油腔滑调,谅解亿下 P2066 ...

  9. jmeter链接数据库,信息全部填写正确,运行之后没有结果

    之前遇到一个很苦恼的问题,jmeter链接数据库,数据库填写的资料全部都没有问题,在其他电脑jmeter上都可以正常链接,但是在我的电脑上运行却总是不出结果, 用mysql链接数据库也一切正常,一直找 ...

  10. SpringCloud微服务实战——搭建企业级开发框架(二十七):集成多数据源+Seata分布式事务+读写分离+分库分表

    读写分离:为了确保数据库产品的稳定性,很多数据库拥有双机热备功能.也就是,第一台数据库服务器,是对外提供增删改业务的生产服务器:第二台数据库服务器,主要进行读的操作. 目前有多种方式实现读写分离,一种 ...