



本节介绍基于Node.js的一个流行的后端框架——Express,同时也会使用Express进行简单的网站开发。
2.1.4节使用Node.js开发了一个Hello World程序,虽然通过HTTP包,用一个简单的文件就能实现一个路由和页面,但这对于一个工程项目的开发来说远远不够。
一个合格的工程从来不是一些简单的文件堆砌,就如同建造一座摩天大楼一样,并不像搭建一个玩具模型的房子,通过简单的拼装就可以完成。建造一座摩天大楼必须拥有坚实的地基和框架,还要有规范和章程才能完成。
Express框架其实就是这样的一款产品,为工程而生。它基于Node.js平台,是一个快速、开放、极简的Web开发框架,官网地址为http://expressjs.com/,如图2-17所示。Express框架从Node.js发布之初就存在,至今已有十多年的历史了。开发者可以使用Express快速地搭建一个具有完整功能的网站,而不是一个简单的网页。
图2-17 Express官方网站
简单来说,Express框架本身是对Node.js中的HTTP模块进行的一层抽象,就是这层抽象使得开发者可以无须注意细节,直接上手进行页面和业务逻辑的开发。Express的主要功能包括:
·设置中间件来响应HTTP请求;
·定义路由表执行不同的HTTP请求动作;
·通过向模板传递参数动态渲染HTML页面。
本小节介绍如何安装Express。Express的功能虽然相当于示例2-1中使用过的HTTP模块,但是不能通过require导入,需要按需安装和下载后才能使用。
不仅仅是Express,作为一个开放的平台,Node.js社区收入了大量开源的JavaScript模块,与安装Node.js时自动安装的HTTP模块不同,这些模块需要使用npm命令按需下载。
注意: 如果使用npm命令时出现下载非常慢或下载失败的情况,请参照附录B中的解决方法。
【示例2-2】 安装Express。
(1)新建项目文件夹,并且通过命令提示行进入该文件夹,如图2-18所示。
图2-18 新建文件夹
(2)使用npm命令初始化Node.js项目,命令如下:
npm init
如果用户是第一次使用项目初始化命令,这里要特别提示一下,初始化命令并不是一次执行完毕,会提出很多问题让用户选择,如项目名称、描述和作者等,如果不想填写,一直按Enter键即可。
初始化命令的执行过程如图2-19所示。注意,本例的入口文件没有使用默认的index.js,而是使用了app.js。
图2-19 初始化Node.js项目
初始化命令执行成功后会生成一个package.json文件,内容如下:
{
"name": "2-2-2",
"version": "1.0.0",
"description": "test",
"main": "app.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}
(3)执行Express的安装命令如下:
//安装Express
npm install express
(4)安装成功后,package.json文件会自动添加Express为依赖项,更改后的内容如下:
//自动更改后的package.json文件
{
"name": "2-2-2",
……
"license": "ISC",
"dependencies": {
"express": "^4.17.1"
}
}
至此,当前项目中成功安装了Express模块。
注意: 老版本的npm安装时,如果没有自动将Express添加为依赖项,可以使用save参数进行添加。
上一节完成了一个Express项目,但它是空白的。本小节在此项目基础上编写一个Express版本的Hello World程序。
【示例2-3】 Express版本的Hello World。
(1)新建一个入口文件app.js,完整的代码如下:
01 //引入Express模块和实例化
02 const express = require('express')
03 const app = express()
04
05 //设定根路由显示Hello World
06 app.get('/', (req, res) => res.send('Hello World!'))
07
08 //监听3000端口为HTTP服务
09 app.listen(3000, () => console.log(`Example app listening on port
3000!`))
程序内容和示例2-1的差别并不大,Express项目中不需要引入HTTP模块,而且写法更简单。实例化Express后,所有的操作只需在该实例中指定路由即可。
(2)使用如下命令运行程序,然后在浏览器中输入http://127.0.0.1:3000,即可访问该页面,如图2-20所示。
node app.js
图2-20 程序运行成功
RESTful API是一种网络应用程序的设计风格和开发方式。使用RESTful风格设计的API路由基于HTTP,支持XML与JSON等格式的数据回传。这种风格设计的接口本身是通过请求方式的限制实现对网络数据资源状态的标识,类似于GET请求某一个路由路径,应当对应的是数据的获取,而使用POST方式进行路由路径的请求,应当是对应数据的增加,例如示例2-3中的一行代码:
app.get('/', (req, res) => res.send('Hello World!'))
指定了一个应用于HTTP的路由,也是该Express项目的根目录,其中“/”是目录地址,即当用户访问http://127.0.0.1:3000本身时就是该地址,而app实例中的get指定了一个状态数据操作接口。
一个HTTP请求可能会采用各种不同的请求方式,参考表2-1。
表2-1 HTTP请求方式
网站的任何操作都有其请求方式,这可以通过浏览器的开发者工具获取。在浏览器中按F12键进入开发者工具,如图2-21所示,被框选的部分就是访问百度页面时获取的GET请求。
图2-21 百度GET请求
每种请求方式都对应着不同的操作,这些操作提供专门的路由地址,这也是RESTful API的本质。RESTful是目前最流行的API设计规范,其核心思想就是对客户端发起的请求进行5种划分,不同的操作对应5种不同的HTTP请求方法,这是以逻辑操作功能为基础进行划分的,而不是传统的API设计以路径方式进行划分。RESTful划分的种类参考表2-2。
表2-2 RESTful划分的种类
符合RESTful的API设计就是所有的API路由符合上述划分。也就是说,相同的请求路径,由于请求方式不同,可能获取的数据结果不同,或执行不同的数据操作。
图2-21中的GET请求返回了一个标准Code为200,这说明GET请求操作成功。任何请求都会返回数字,这些返回数字被称为状态码。状态码标志着这次请求是成功还是出现了什么问题。
不同的请求方式返回的状态码也可能不同,常见的状态码含义见表2-3。
表2-3 不同请求方式返回的状态码的含义
注意: 状态码还可以用来表示其他含义,如300系列的重定向、400系列的客户端错误和500系列的服务器错误等。通过HTTP查看具体的状态码并且了解其含义,可以方便地定位问题所在。