Node.js|Express框架概述


Express框架

  • 1 初始Express
    • 1.1 Express介绍
    • 1.2 安装Express
    • 1.3 利用Express搭建Web服务器
  • 2 Express中间件
    • 2.1 什么是中间件
    • 2.2 app.get()中间件
    • 2.3 app.post()中间件
    • 2.4 app.use()中间件
    • 2.5 利用express.static()中间件处理静态资源
    • 2.6 利用中间件处理错误
  • 3 Express模块化路由
  • 4 Express接收请求参数
    • 4.1 接受GET请求
    • 4.2 接收POST请求参数
    • 4.3 接收路由参数
  • 5 Webstorm中创建Express项目
  • 6 nodemon模块

1 初始Express 1.1 Express介绍 Express是目前流行的基于Node.js运行环境的Web应用程序开发框架,它简洁且灵活,为Web应用程序提供了强大的功能。Express提供了一个轻量级模块,类似于jQuery(封装的工具库),它把Node.js的HTTP模块的功能封装在一个简单易用的接口中,用于扩展HTTP模块的功能,能够轻松地处理服务器的路由、响应、Cookie和HTTP请求的状态。
Express的优势:
(1)简洁的路由定义方式。
(2)简化HTTP请求参数的处理。
(3)提供中间件机制控制HTTP请求。
(4)拥有大量第三方中间件。
(5)支持多种模版引擎。
1.2 安装Express 这里使用npm包管理工具安装Express。
新建一个空文件夹demo,用来放置创建的Express框架,然后在该文件夹的路径下面输入cmd,打开命令提示符窗口。
Node.js|Express框架概述
文章图片

打开的窗口自动进入该路径下了。
Node.js|Express框架概述
文章图片

然后执行以下命令:
// 项目初始化 npm init -y // 安装 npm install express --save

Node.js|Express框架概述
文章图片

查看Express的版本:
npm list express

Node.js|Express框架概述
文章图片

1.3 利用Express搭建Web服务器 利用Express搭建Web服务器的基本步骤:
  1. 引入express模块;
  2. 调用express()方法创建服务器对象;
  3. 定义路由;
  4. 调用listen()方法监听端口。
app.get()方法的示例代码:
app.get('/', (req, res) => { console.log(req, res); });

示例:利用Express搭建Web服务器(使用vscode)
第一步:在demo目录下创建文件夹src,在src下创建server.js文件:
Node.js|Express框架概述
文章图片

第二步:编写server.js,代码如下
// 引入express模块 const express = require("express"); // 创建Web服务器对象 const app = express(); // 定义GET路由,接收/处理客户端的GET请求 app.get("/", (req, res) => { // 对客户端做出响应,send()方法会根据内容的类型自动设置请求头 res.end("hello express"); }) // 监听3000端口 app.listen(3000);

第三步:启动服务器。打开vscode最上方的Terminal命令,选择New Ternimal,打开终端,这时终端显示如下:
Node.js|Express框架概述
文章图片

运行server.js文件需要再进入到src目录下面,因此在终端输入:cd src,在src目录下执行以下命令,这时服务器就成功启动了。
node server.js

Node.js|Express框架概述
文章图片

第四步:访问测试。在浏览器中输入地址:localhost:3000,访问结果如下:
Node.js|Express框架概述
文章图片

2 Express中间件 2.1 什么是中间件 Express通过中间件接收客户端发来的请求,并对请求做出响应,也可以将请求交给下一个中间件继续处理。
Express中间件指业务流程中的中间处理环节,可以把中间件理解为客户端请求的一系列方法。如果把请求比作水流,那么中间件就是阀门,阀门可以控制水流是否继续向下流动,也可以在当前阀门处对水流进行排污处理,处理完成后再继续向下流动。
Node.js|Express框架概述
文章图片

中间件机制可以实现哪些应用?
  • 路由保护:当客户端访问登录页面时,可以先使用中间件判断用户的登录状态,如果用户未登录,则拦截请求,直接响应提示信息,并禁止用户跳转到登录页面。
  • 网站维护公告:在所有路由的最上面定义接收所有请求的中间件,直接为客户端做出响应,并提示网站正在维护中。
  • 自定义404页面:在所有路由的最上面定义接收所有请求的中间件,直接为客户端做出响应,并提示404页面错误信息。
中间件主要由中间件方法和请求处理函数这两个部分构成。中间件方法由Express 提供,负责拦截请求。请求处理函数由开发人员编写,负责处理请求。
常用的中间件方法有app.get()、app.post()、app.use(),其基本语法形式如下。
app.get('请求路径', '请求处理函数'); // 接收并处理GET请求 app.post('请求路径', '请求处理函数'); // 接收并处理POST请求 app.use('请求路径', '请求处理函数'); // 接收并处理所有请求

2.2 app.get()中间件 当客户端向服务器端发送GET请求时,app.get()中间件方法会拦截GET请求,并通过app.get()中间件中的请求处理函数对GET请求进行处理。
app.get('/', (req, res, next) => { next(); });

同一个请求路径可以设置多个中间件,表示对同一个路径的请求进行多次处理,默认情况下Express会从上到下依次匹配中间件。
示例:使用app.get()定义中间件并返回req.name的值
// 引入express模块 const express = require("express"); // 创建Web服务器对象 const app = express(); // 定义中间件 app.get("/request", (req, res, next) => { req.name = "橘猫吃不胖"; next(); // 启动下一个中间件 }) app.get("/request", (req, res) => { res.end(req.name); }) // 监听3000端口 app.listen(3000);

启动服务器,在浏览器中输入:localhost:3000/request,点击回车,出现以下页面:
Node.js|Express框架概述
文章图片

2.3 app.post()中间件 当浏览器向服务器发送POST请求时,app.post()定义的中间件会接收并处理POST请求。
示例:使用app.post()定义中间件发送post请求
第一步:新建一个用于发送post请求的表单index.html

第二步:定义app.post()中间件,接受并处理浏览器发送的POST请求,返回req.name的值
const express = require("express"); const app = express(); // 定义中间件 app.post("/post", (req, res, next) => { req.name = "橘猫吃不胖"; next(); }) app.post("/post", (req, res) => { res.end(req.name); }) // 监听4000端口 app.listen(4000);

第三步:启动服务器,在浏览器中打开index.html,出现一个按钮,点击该按钮,就会跳转到localhost:4000/post页面
Node.js|Express框架概述
文章图片

2.4 app.use()中间件 通过app.use()定义的中间件既可以处理GET请求又可以处理POST请求。在多个app.use()设置了相同请求路径的情况下,服务器都会接收请求并进行处理。
示例:使用app.use()定义中间件,处理GET和SET请求
const express = require("express"); const app = express(); // 定义中间件 app.use("/form", ((req, res, next) => { req.name = "橘猫吃不胖"; next(); })) app.use("/form", (req, res) => { res.end(req.name); }) // 监听3000端口 app.listen(3000);

运行服务器,在浏览器中打开localhost:3000/form,结果如图所示,可以看出app.use()可以处理GET请求。
Node.js|Express框架概述
文章图片

编写form.html文件,代码如下:

在浏览器中打开该文件,点击页面上的按钮,也进入到了该页面。
Node.js|Express框架概述
文章图片

app.use()方法的请求路径参数可以省略,省略时表示不指定路径,所有的请求都会被处理。
示例:使用app.use()定义一个省略请求路径的中间件,使用app.post()定义两个带有请求路径的中间件,观察当有多个中间件时的执行结果
const express = require("express"); const app = express(); app.use((req, res, next) => { req.user = {}; next(); }) app.post("/post", (req, res, next) => { req.user.age = "30"; next(); }) app.post("/post", (req, res) => { res.end(req.user.age); }) // 监听3000端口 app.listen(3000);

编写form.html文件,代码如下:

在浏览器中运行该文件,点击页面中的按钮,就会跳转到以下页面:
Node.js|Express框架概述
文章图片

示例:使用app.use()定义一个省略请求路径的中间件,使用app.get()定义两个带有请求路径的中间件,观察当有多个中间件时的执行结果
const express = require("express"); const app = express(); app.use((req, res, next) => { req.user = {}; next(); }) app.get("/get", (req, res, next) => { req.user.name = "橘猫吃不胖"; next(); }) app.get("/get", (req, res) => { res.end(req.user.name); }) // 监听3000端口 app.listen(3000);

启动服务器,在浏览器中输入localhost:3000/get,同样也会出现以下页面:
Node.js|Express框架概述
文章图片

如果将请求处理函数作为函数的返回值传给app.use(),那么该返回值也可以被app.use()接收,语法如下:
app.use(fn()); function fn(obj) { return function (req, res, next) { next(); }; };

示例:在调用fn()函数时传入参数
const express = require("express"); const app = express(); // 在调用fn()函数时传入参数 app.use(fn({a: 1})); function fn(obj) { return function (req, res, next) { // 根据不同的obj.a的值打印不同的信息 if (obj.a == 1) { console.log(req.url); } else { console.log(req.method); } next(); } }//使用app.get()中间件定义/fn路由 app.get("/fn", (req, res) => { res.end("OK"); })// 监听3000端口 app.listen(3000);

启动服务器,在浏览器中输入localhost:3000/fn,页面上会显示OK。
Node.js|Express框架概述
文章图片

同时在终端也会打印出req.url的值:
Node.js|Express框架概述
文章图片

2.5 利用express.static()中间件处理静态资源 express.static()是Express框架提供的内置中间件,它接收静态资源访问目录作为参数。
使用express.static()内置中间件可以方便地托管静态文件,在客户端访问服务器的静态资源时使用。常用的静态资源有图片、CSS、JavaScript和HTML文件等。
express.static()参数是静态资源所在的目录,它需要作为app.use()的参数使用,示例代码如下:
app.use(express.static('public'));

示例:实现静态资源访问
第一步:在src目录下新建public文件夹,用于存放静态文件,在该目录下新建一个文件夹images,存放一个图片文件
Node.js|Express框架概述
文章图片

第二步:在src目录下新建static.js文件,代码如下
const express = require("express"); const app = express(); // 静态资源处理 app.use(express.static("public")); // 监听3000端口 app.listen(3000);

第三步:启动服务器,在浏览器中输入:localhost:3000/images/1.jpg,页面上就会显示出来放在images文件夹下面的图片

2.6 利用中间件处理错误 在程序执行的过程中,不可避免的会出现一些无法预料的错误,比如文件读取失败、数据库连接失败等。这时候就需要用到错误处理中间件了,用它来集中处理错误。
利用app.use()定义错误处理中间件的示例代码如下:
app.use((err, req, res, next) => { console.log(err.message); });

示例:进行文件读取操作,返回文件读取失败的错误信息
const express = require("express"); const fs = require("fs"); const app = express(); // 使用app.get()中间件进行文件读取操作 app.get("/readFile", (req, res, next) => { // 读取a.txt文件 fs.readFile("./a.txt", "utf8", (err, result) => { if (err !== null) { // 如果错误信息不为空,将该信息传给下一个中间件 next(err); } else { res.send(result); } }) }) // 错误处理中间件 app.use((err, req, res, next) => { // 设置响应状态码为500,并发送错误信息 res.status(500).send(err.message); }) app.listen(3000);

启动服务器,在浏览器中输入localhost:3000/readFile,由于当前目录下没有a.txt文件,因此会报错:
Node.js|Express框架概述
文章图片

打开浏览器的开发者工具,会显示状态码500。
Node.js|Express框架概述
文章图片

3 Express模块化路由 虽然可以使用app.get()方法和app.post()方法来实现简单的路由功能,但没有对路由进行模块化管理。在实际的项目开发中,不推荐将不同功能的路由都混在一起存放在一个文件中,因为随着路由的种类越来越多,管理起来会非常麻烦。为了方便路由的管理,通过express.Router()实现模块化路由管理。
express.Router()方法用于创建路由对象route,然后使用route.get()和route.post()来注册当前模块路由对象下的二级路由,这就是一个简单的模块化路由。
express.Router()方法定义route对象的示例代码如下:
const route = express.Router();

route对象下可以定义二级路由,示例代码如下:
route.get('请求路径', '请求处理函数'); // 接收并处理route 下的GET 请求 route.post('请求路径', '请求处理函数'); // 接收并处理route 下的POST 请求

route对象创建成功后,使用app.use()注册route模块化路由,示例代码如下:
app.use('请求路径', route);

下面通过案例演示express.Router()如何定义二级路由。
示例:express.Router()定义二级路由
const express = require("express"); const app = express(); // 定义route对象 const route = express.Router(); // 在route路由下创建二级路由 route.get("/index", (req, res) => { res.send("欢迎来到主页"); }) // app.use()注册route模块化路由 app.use("/route", route); // 监听3000端口 app.listen(3000);

启动服务器,在浏览器中打开localhost:3000/route/index,访问结果如下:
Node.js|Express框架概述
文章图片

express.Router()方法可以将同一类路由放在一个单独的文件中,每个单独的文件表示一个单独的模块,通过文件的名称来区分路由的功能。
例如,在home.js文件中定义“博客前台”路由,在admin.js文件中定义“博客后台”路由。下面进行案例演示。
新建home.js文件,代码如下:
const express = require("express"); // 定义home对象 const home = express.Router(); // 在home模块化路由下创建路由 home.get("/index", (req, res) => { res.send("欢迎来到博客前台"); }) // 将home导出 module.exports = home;

新建admin.js文件,代码如下:
const express = require("express"); const admin = express.Router(); // 在admin模块化路由下创建路由 admin.get("/index", (req, res) => { res.send("欢迎来到博客后台"); }) // 导出admin module.exports = admin;

新建module.js文件,代码如下:
const express = require("express"); const home = require("./home"); // 导入home const admin = require("./admin"); // 导入admin const app = express(); // 注册home模块化路由 app.use("/home", home); app.use("/admin", admin); app.listen(3000);

启动服务器(module.js),在浏览器中输入:localhost:3000/home/index,就能访问到博客前台:
Node.js|Express框架概述
文章图片

在浏览器中输入localhost:3000/admin/index,就会访问到博客后台:
Node.js|Express框架概述
文章图片

4 Express接收请求参数 4.1 接受GET请求 Express框架中的req.query用于获取GET请求参数,框架内部会将GET参数转换为对象并返回。利用req.query获取GET请求参数的示例代码如下。
app.get('/', (req, res) => { res.send(req.query); });

示例:获取GET请求参数
const express = require("express"); const app = express(); app.get("/query", (req, res) => { // 获取get请求参数 res.send(req.query); }) app.listen(3000);

启动服务器,在浏览器中输入http://localhost:3000/query?name=zhangsan&age=12,其中http://localhost:3000/query表示服务器的请求地址,“?”之后是请求的参数,这部分可以自己编写,参数与参数之间使用“&”隔开,访问结果如下:
Node.js|Express框架概述
文章图片

示例:使用表单发起GET请求,参数会被自动添加到请求地址后面,创建index.html,代码如下
用户名:
密码:

query.js代码如下:
const express = require("express"); const app = express(); app.get("/query", (req, res) => { // 获取get请求参数 res.send(req.query); }) app.listen(3000);

启动服务器,在浏览器中打开index.html页面,输入用户名与密码:
Node.js|Express框架概述
文章图片

点击提交,页面上显示出了获取到的GET请求参数:
Node.js|Express框架概述
文章图片

4.2 接收POST请求参数 Express中的req.body用于获取POST请求参数,需要借助第三方body-parser模块将POST参数转换为对象形式。利用req获取POST请求参数的示例代码如下。
app.post('/body', (req, res) => { res.send(req.body); });

body-parser是一个解析HTTP请求体的模块,使用这个模块可以处理POST请求参数,使用起来非常方便。使用body-parser模块处理表单数据的示例代码如下:
app.use(bodyParser.urlencoded({ extended: false }));

{ extended: false}表示在方法的内部使用querystring系统模块来处理POST请求参数;
{ extended: true}表示使用qs第三方模块进行处理。
示例:处理POST请求参数
第一步:安装body-parser模块
npm install body-parser@1.18.3 --save

第二步:编写query.js文件
const express = require("express"); const bodyParsee = require("body-parser"); const app = express(); app.use(bodyParsee.urlencoded({ extended: false })); app.post("/query", (req, res) => { // 获取get请求参数 res.send(req.body); }) app.listen(3000);

第三步:编写index.html文件
用户名:
密码:

第四步:启动服务器,在浏览器中打开index.html页面,输入用户名和密码,点击提交,于是获取到了POST请求参数
Node.js|Express框架概述
文章图片

Node.js|Express框架概述
文章图片

4.3 接收路由参数 在定义路由时,可以在请求路径中传递参数,例如请求路径“/find/:id”中的“:id”是一个参数占位符,当浏览器向“/find/:id”地址发送请求时,“:id”对应的值就是参数值。
通常情况下,把写在路由请求路径中的参数称为路由参数。通过请求路径传递参数,可以让路由代码看起来非常美观,且请求参数会被清晰地展示出来。
Express路由参数的示例代码如下:
app.get('/find/:id', (req, res) => { res.send(req.params); });

示例:接收路由参数
const express = require("express"); const app = express(); app.get("/find/:id", (req, res) => { res.send(req.params); }) app.listen(3000);

启动服务器,浏览器中输入:localhost:3000/find/123,访问结果如下:
Node.js|Express框架概述
文章图片

示例:实现多个参数的传递
const express = require("express"); const app = express(); app.get("/find/:id/:name/:age", (req, res) => { res.send(req.params); }) app.listen(3000);

启动服务器,在浏览器中输入http://localhost:3000/find/123/zhangsan/14,访问结果如下。
Node.js|Express框架概述
文章图片

在本段代码中,通过:id、:name、:age分别传递用户id、用户名和年龄。
5 Webstorm中创建Express项目 1、打开WebStorm,选择File——New——Project。
Node.js|Express框架概述
文章图片

2、选项Express,然后在Location后面修改当前项目存放的路径,然后点击创建。
Node.js|Express框架概述
文章图片

3、修改项目使用的端口号,在bin文件夹下找到www.js文件,在里面的第15行代码中,可以修改"3000"为想要的端口号,一般修改为"8089"。
Node.js|Express框架概述
文章图片

4、在当前项目中,public文件夹为项目的静态资源目录,routes文件夹为路由文件夹,views为视图文件夹(页面文件),app.js为项目的启动文件。
Node.js|Express框架概述
文章图片

6 nodemon模块 安装nodemon模块后,当源程序发生改变,无需重新启动服务器,程序也能自动运行。
使用方法:
1、安装模块:
npm install nodemon

2、在package.json文件中第6行代码中,node换成nodemon。
Node.js|Express框架概述
文章图片

3、启动项目,在终端中输入启动命令:
npm start

【Node.js|Express框架概述】启动后,无需重新启动服务器,源代码更新服务器也会自动更新

    推荐阅读