一、Express简介
Express是一个基于Node.js平台,且快速、开放、极简的web开发框架,提供了一系列强大的特性,帮助你创建各种web和移动设备应用。同时也有丰富的Http快捷方法和任意排列组合的Connect中间件,让我们能创建健壮、友好的API变得既快速又简单。Express不对Node.js已有的特性进行二次抽象,只是在它之上扩展了web应用所需的基本功能。
安装express:npm install express --save
二、创建简单的服务器
新建一个目录,安装express
后,在index.js
中来创建一个简单的服务器,大致体会一下express的用法:
js
const express = require('express')
// 直接调用exprss创建服务器实例
const app = express()
// 处理get请求
app.get('/', (req, res) => {
res.send('hello world')
})
// 开启监听服务
app.listen(3000, () => {
console.log('启动...')
})
打开浏览器输入http://127.0.0.1:3000/
,请求成功了,一个服务器就这样创建完成:

上面代码块中,res.send
方法不仅可以返回字符串,还可以返回代码片段:
js
const express = require('express')
// 直接调用exprss创建服务器实例
const app = express()
// 处理get请求
app.get('/login', (req, res) => {
res.send(`
<html>
<h1>Hello World</h1>
</html>
`)
})
// 开启监听服务
app.listen(3000, () => {
console.log('启动...')
})
打开浏览器输入http://127.0.0.1:3000/login
,正确显示了网页:

三、中间件
可以为请求处理提供多个回调函数,这些回调函数就是常说的中间件,通过调用这些回调函数提供的next
方法可以继续执行第二个、第三个回调函数。看个示例:
js
const express = require('express')
// 直接调用exprss创建服务器实例
const app = express()
app.get('/login', (req, res, next) => {
console.log('验证token')
const isValid = true
if (isValid) {
// 放行,执行下一个回调函数
next()
} else {
res.send('请求错误')
}
}, (req, res, next) => {
console.log('查询数据库')
res.send('请求成功')
})
// 开启监听服务
app.listen(3000, () => {
console.log('启动...')
})
打开浏览器输入http://127.0.0.1:3000/login
,显示请求成功:

可以利用中间件为路由定义前提条件,如果在现有路径上已执行完正确的程序逻辑才可将控制权交给下一个中间件去执行。为了代码可读性,可以重写一下代码,将中间件用数组传入:
js
const express = require('express')
// 直接调用exprss创建服务器实例
const app = express()
const cb1 = (req, res, next) => {
console.log('验证token')
const isValid = true
if (isValid) {
// 放行,执行下一个回调函数
next()
} else {
res.send('请求错误')
}
}
const cb2 = (req, res, next) => {
console.log('查询数据库')
res.send('请求成功')
}
app.get('/login', [cb1, cb2])
// 开启监听服务
app.listen(3000, () => {
console.log('启动...')
})
当然上面两种写法可以混用,假设cb1
函数是需要被共用的,其余逻辑是特定路由下的,可以这么写更容易理解:
js
const express = require('express')
// 直接调用exprss创建服务器实例
const app = express()
const cb1 = (req, res, next) => {
console.log('验证token')
const isValid = true
if (isValid) {
// 放行,执行下一个回调函数
next()
} else {
res.send('请求错误')
}
}
app.get('/login', [cb1], (req, res, next) => {
console.log('查询数据库')
res.send('请求成功')
})
// 开启监听服务
app.listen(3000, () => {
console.log('启动...')
})
Express是一个自身功能极简,完全是由路由和中间件构成的一个web开发框架,从本质上来说,一个Express应用就是在调用各种中间件。
中间件可以访问请求对象,响应对象和web应用中处于请求-响应循环的流程,也就是next。
中间件的功能包括:
- 执行任何代码
- 修改请求和响应对象
- 终结请求-响应循环
- 调用堆栈中的下一个中间件
四、多种中间件应用
Express应用可使用以下几种中间件:
- 应用级中间件
- 路由级中间件
- 错误处理中间件
- 内置中间件
- 第三方中间件
应用级中间件
应用级中间件绑定到app对象,使用app.use()和app.METHOD(),其中METHOD是需要处理的http请求的方法,例如get,post、put等。例如验证token的方法是所有接口都需要用到的,可以这么写:
js
const express = require('express')
// 直接调用exprss创建服务器实例
const app = express()
// login请求处理写在use前面,不受应用级中间件影响
app.get('/login', (req, res) => {
res.send('登录')
})
// 没有挂载路由的中间件,后面应用的每个请求都会执行该中间件
app.use(function(req, res, next) {
console.log('验证token')
next()
})
app.get('/list', (req, res) => {
res.send('列表')
})
// 开启监听服务
app.listen(3000, () => {
console.log('启动...')
})
也可以为某个路由指定特定的中间件:
js
const express = require('express')
// 直接调用exprss创建服务器实例
const app = express()
// 只有/home路由下会执行该中间件
app.use('/home', function(req, res, next) {
console.log('home 中间件')
next()
})
app.get('/home', (req, res) => {
res.send('home')
})
// 开启监听服务
app.listen(3000, () => {
console.log('启动...')
})
路由级中间件
路由级中间件和应用级中间件一样,只是它绑定的对象为express.Router()。创建一个新的文件indexRouter.js
,写入以下代码:
js
const express = require('express')
const router = express.Router()
// 路由级别中间件
router.get('/index', (req, res) => {
res.send('index')
})
router.get('/login', (req, res) => {
res.send('login')
})
module.exports = router
在index.js
中引入:
js
const express = require('express')
const IndexRouter = require('./router/indexRouter')
// 直接调用exprss创建服务器实例
const app = express()
app.use(function(req, res, next) {
console.log('验证token')
next()
})
// 只要匹配到/api,就会执行路由中间件
app.use('/api', IndexRouter)
// 开启监听服务
app.listen(3000, () => {
console.log('启动...')
})
错误处理中间件
错误处理中间件和其他中间件类似,注意错误中间件要放在最后:
js
const express = require('express')
const IndexRouter = require('./router/indexRouter')
// 直接调用exprss创建服务器实例
const app = express()
app.use('/', IndexRouter)
// 错误中间件要放到最后
app.use(function(req, res) {
res.status(404).send('error 发生了')
})
// 开启监听服务
app.listen(3000, () => {
console.log('启动...')
})
打开浏览器输入http://127.0.0.1:3000/home
,显示错误:

内置中间件
express.static
是Express唯一内置的中间件,它基于serve-static
,负责在Express应用中托管静态资源,每个应用可有多个静态目录。
js
const express = require('express')
const IndexRouter = require('./router/indexRouter')
// 直接调用exprss创建服务器实例
const app = express()
app.use(express.static('public'))
app.use(express.static('files'))
app.use(express.static('uploads'))
// 开启监听服务
app.listen(3000, () => {
console.log('启动...')
})
第三方中间件
第三方中间件是额外需要安装的node模块并在应用中加载,可以在应用级加载,也可以在路由级加载,例如安装一个解析cookie的中间件:cookie-parser
:
js
const express = require('express')
const cookieParser = require('cookie-parser')
// 直接调用exprss创建服务器实例
const app = express()
// 加载用于解析cookie的中间件
app.use(cookieParser())
// 开启监听服务
app.listen(3000, () => {
console.log('启动...')
})
五、获取请求传参
路由请求传参在中间件的参数中可直接访问,如果是get请求,则通过query获取,如果是post请求,则通过body获取。 get请求示例如下,首先在indexRouter
中准备一个get路由中间件,打开浏览器访问http://127.0.0.1:3000/index?username=123&password=abc
:
js
const express = require('express')
const router = express.Router()
// 路由级别中间件
router.get('/index', (req, res) => {
console.log(req.query) // 输出:{ username: '123', password: 'abc' }
res.send('index')
})
module.exports = router
post请求示例如下,如果要正确解析post传参,需要配置解析post参数的中间件:
js
const express = require('express')
const IndexRouter = require('./router/indexRouter')
// 直接调用exprss创建服务器实例
const app = express()
// 配置用于解析post参数的中间件,express已内置
// urlencoded只响应form表单类型的参数:username=123&password=abc
app.use(express.urlencoded({extended: false}))
// json响应json类型的传参: { "username": "123", "password": "abc" }
app.use(express.json())
app.use(function(req, res, next) {
console.log('验证token')
next()
})
app.use('/', IndexRouter)
// 开启监听服务
app.listen(3000, () => {
console.log('启动...')
})
在indexRouter.js
中配置一个post请求:
js
router.post('/login', (req, res) => {
console.log(req.body) // 用body获取post传参
res.send('登录')
})
借助一个浏览器插件发送post请求:

六、托管静态资源
通过Express内置的express.static
可以方便地托管静态文件,例如图片、CSS、JavaScript文件等。 将静态资源文件所在目录作为传参传递给express.static
中间件就可以提供访问,如果在public目录下放置了图片、css和JavaScript,可以:
js
// 可添加多个静态资源目录,express.static会按中间件顺序查找
app.use(express.static('public'))
app.use(express.static('files'))
放在public目录下的文件可以这么访问:
text
http://127.0.0.1:3000/css/style.css
http://127.0.0.1:3000/js/app.js
http://127.0.0.1:3000/images/avatar.png
所有文件的路径都是相对于目录存放的,因此目录名不会出现在请求的url中。 如果希望通过express.static访问的文件存在一个虚拟目录,可以为其指定一个挂载路径的方法实现:
js
app.use('/static', express.static('public'))
访问路径:
text
http://127.0.0.1:3000/static/css/style.css
http://127.0.0.1:3000/static/js/app.js
http://127.0.0.1:3000/static/images/avatar.png
好了,关于Express的基础入门就到这啦。