5分钟快速上手 Express
前言
Express 官方表明,Express 是一个极简且灵活的 Node.js Web 应用框架,它为 Web 和移动应用提供了一组强大的功能,因此能够帮助我们快速的搭建 Web 服务器。
在 Express 出现之前,我们需要处理很多繁琐且没有技术含量的内容,例如:从获取路由 -> 解析路由 -> 分配路由 -> 处理路由等相关操作;我们需要自己手动去实现静态/动态资源的处理,例如:get 或者 post 参数的解析,cookie 的解析,日志的处理等相关操作。
Express 出现之后,就能帮助我们省去大量繁琐的环节, 让我们只用关注核心业务逻辑的开发,因为 Express 的相关插件已经帮我们集成,我们只需要按需引入插件即可。
创建项目
首先,创建一个项目文件夹,例如:文件名称叫做 express-template
。
然后,在项目根目录的终端命令行输入:npm init
,初始化 package.json
项目文件。

其次,继续在终端命令行输入:npm install express
安装 express 包,接着创建 index.js 文件,在文件中增加如下内容:
// 1.导入express
const express = require('express')
// 2.调用 express 方法, 创建服务端实例对象
const app = express()
app.get('/', (req, res, next)=>{
res.writeHead(200, {
'Content-Type': 'text/plain; charset=utf-8;'
})
res.end('Hello Express!')
})
// 3.告诉服务端需要监听哪一个端口
app.listen(3000, ()=>{
console.log('express 服务启动成功!')
})
最后,在命令行终端输入:node index.js
,如果显示如下内容,则表示一个 Express 项目成功。

在浏览器中输入:http://localhost:3000 ,显示上述代码中返回的内容。

处理静态网页
在 Express 中处理静态网页需要使用 Express 提供的内置中间件函数 express.static
,使用方式为在代码中增加如下代码:app.use(express.static(path.join(__dirname, 'public')))
。
// 1.导入express
const express = require('express')
const path = require('path')
// 2.调用express方法, 创建服务端实例对象
const app = express()
// 处理静态资源
app.use(express.static(path.join(__dirname, 'public')))
app.get('/', (req, res, next)=>{
res.writeHead(200, {
'Content-Type': 'text/plain; charset=utf-8;'
});
res.end('Hello Express!')
});
// 3.告诉服务端需要监听哪一个端口
app.listen(3000, ()=>{
console.log('express 服务启动成功!')
})
处理动态网页
在 Express 中处理动态网页需要使用 Express 提供的 app.set(name, value) API 来告诉 express 动态资源存储在什么地方以及 express 动态网页使用的是什么模板引擎。此时我们可以在根目录下创建一个名称 views
的文件夹,同时在文件夹中创建 index.ejs
项目模板。

接着就是监听请求,返回渲染之后的动态网页,注意在 res.render
函数的第一个参数为 views
文件夹下的项目模板文件名称,第二个参数为传递的参数。
// 1.导入express
const express = require('express')
const path = require('path')
// 2.调用express方法, 创建服务端实例对象
const app = express()
// 处理静态资源
app.use(express.static(path.join(__dirname, 'public')))
// 处理动态资源
// 1.告诉 express 动态资源存储在什么地方
app.set('views', path.join(__dirname, 'views'))
// 2.告诉 express 动态网页使用的是什么模板引擎
app.set('view engine', 'ejs')
// 3.监听请求, 返回渲染之后的动态网页
app.get('/', (req, res, next)=>{
// 注意点: express给请求对象和影响对象添加了很多自定义的方法
res.render('index', {msg:'Hello Express!'})
})
// 3.告诉服务端需要监听哪一个端口
app.listen(3000, ()=>{
console.log('express 服务启动成功!')
});
处理路由
在 Express 中处理路由需要使用 Express 提供的 app.get() API,这是通过 express 处理路由的一种方式。
值得注意的是,响应对象的json
方法是 express 给响应对象扩展的,这个方法会自动将对象转换成字符串之后返回,这个方法还会自动帮助我们设置响应头。
// 通过 express 处理路由
// 处理 get 请求
app.get('/api/blog/list', (req, res, next)=>{
res.end('express nodes')
})
app.get('/api/user/login', (req, res, next)=>{
res.json({
name:'lisi',
age:21,
method: 'get'
})
})
// 处理 post 请求
app.post('/api/blog/detail', (req, res, next)=>{
res.end('Hello Express!')
})
app.post('/api/user/register', (req, res, next)=>{
res.json({
name:'lisi',
age:21,
method: 'post'
})
})
另一种处理路由的方式为使用 Express 提供的 express.Router() 方法来处理路由:
首先,在项目根目录创建 router
文件夹。其次,在文件夹中创建 user.js
文件。

然后,在文件中增加如下代码,也就是上方示例图片中的代码:
const express = require('express')
const router = express.Router()
// 会将注册的地址和当前的地址拼接在一起来匹配
// /api/user/login
router.get('/login', (req, res, next) => {
res.json({
name: 'lisi',
age: 21,
method: 'get'
})
})
router.post('/register', (req, res, next) => {
res.json({
name: 'lisi',
age: 21,
method: 'post'
})
})
module.exports = router
最后,回到项目根目录中的 index.js
文件中,在此文件中增加如下代码:
// 引入 router 文件夹中定义的路由
const userRouter = require('./router/user')
// 通过 express 提供的 app.use() 的方式处理路由
app.use('/api/user', userRouter)
接着,在浏览器中访问 http://localhost:3000/api/user/login ,就会在浏览器中显示在 /router/user.js
中定义的关于 /login
的 get
请求的路由。

处理请求参数
在 Express 中处理请求参数需要使用 Express 提供的内置中间件函数 express.json() 以及 express.urlencoded()。
其中 express.json([options])
方法能够告诉 express 解析 application/json
类型的请求参数,
而 express.urlencoded([options])
方法能够告诉 express 解析表单类型的请求参数。
最后,express 会将解析之后的内容转换成对象的 post 请求参数放到请求对象的 body 属性中。
app.get('/get', (req, res, next)=>{
// express 会将 get 的请求参数转换成对象之后,放到请求对象的 query 属性中
console.log(req.query)
})
app.use(express.json()) // 告诉 express 能够解析 application/json 类型的请求参数
app.use(express.urlencoded({extended: false})) // 告诉 express 能够解析表单类型的请求参数 application/x-www-form-urlencoded
// express 会将解析之后的内容转换成对象的 post 请求参数放到请求对象的 body 属性中
app.post('/post', (req, res, next)=>{
console.log(req.body)
})
处理 Cookies
在 Express 中处理 Cookies 需要使用 Express 提供的 res.cookie() API,同时还要使用 cookie-parser 这个第三方插件。
const cookieParser = require('cookie-parser')
// 处理cookie
app.get('/setCookie', (req, res, next)=>{
res.cookie('username', 'lisi', {httpOnly: true, path: '/', maxAge: 10000})
res.end()
})
app.use(cookieParser())
app.get('/getCookie', (req, res, next)=>{
console.log(req.cookies)
})
正确处理 next
在 Express 中,app.use() 既可以处理没有路由地址的请求,也可以处理有路由地址请求,同样既可以处理 get 请求,也可以处理 post 请求。
值得注意的是,在处理请求的时候都是从上至下依次判断的,谁满足条件,就先处理谁。如果在处理请求的回调函数中没有调用 next 方法,那么处理完之后就不会再继续往下判断,反之,如果调用 next 方法,处理完之后还是会继续往下判断的。
补充知识点:
app.get()
专门用于处理 GET 请求,而app.use()
可以处理任何类型的请求,实际上app.use()
是一个更通用的中间件挂载方法,也可用于挂载路由处理器。
例如,在 index.js
中增加如下代码,注意把处理路由的方式一注释掉,两种方式不能同时存在。
// next 的使用方式
app.use((req, res, next) => {
console.log('use1 没有路由地址')
next()
})
app.use('/', (req, res, next) => {
console.log('use2 有路由地址')
next()
})
app.get('/api', (req, res, next) => {
console.log('get /api')
next()
})
app.get('/api/user', (req, res, next) => {
console.log('get /api/user')
next()
})
在项目终端命令行输入:node index.js
,然后在浏览器中访问 http://localhost:3000/api/user ,接着就会在终端命令行显示如下内容:

这说明,默认情况下 express 会从上至下的匹配路由处理,一旦匹配到就会执行,执行完毕之后如果没有调用 next 就停止,如果调用 next 就继续向下匹配。值得研究的是,我们可以将同一个请求的多个业务逻辑拆分到不同的方法中去处理,这样可以提升代码的可读性和可维护性, 以及保证代码的单一性。
因此,next 的正确打开方式为如下代码:
app.get(
'/api/user',
(req, res, next) => {
console.log('验证用户是否登陆')
next()
},
(req, res, next) => {
console.log('用户已经登陆, 可以查看用户信息')
}
)
处理错误
由于在处理请求的时候会从上至下的匹配,所以只要前面的路由都没有匹配到,就会执行下面的 use,正确处理错误的方式为在项目中增加如下代码:
// 引入 http-errors 第三方包,用于处理错误
const createError = require('http-errors')
app.use((req, res, next) => {
next(createError(404))
})
app.use((err, req, res, next) => {
console.log(err.status, err.message)
res.end(err.message)
})
接着,在命令行终端输入:node index.js
启动项目。
然后,在浏览器中访问一个不存在的路由:http://localhost:3000/api/user/123 ,命令行终端就会显示打印的错误信息:

同样在浏览器也会显示出 http-errors
这个第三包返回至浏览器中的错误信息:

总结
Express 最早的版本是在2010年发布的,目前 Express 最新的版本是 4.19.2
,而最新的 beta 版本是 5.0.0-beta.3
,这意味着 Express 团队在一直持续维护着 Express,并且 Express 5.0 的版本不久也会正式发布。
虽然 Express 是一个古老的框架,但是它并没有过时。这是因为公司老项目仍然在使用,并且 Koa 就是由 Express 原班人马打造的。况且国内的企业级 Node.js 框架 Egg.js 就是由 Koa 打造的。
因此我们学会 Express 能够更快的学习 Koa 和 Egg.js,甚至是 Nest.js。
转载自:https://juejin.cn/post/7365119428840570943