Express框架介绍与基础入门

一、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的基础入门就到这啦。

相关推荐
人间观察员1 分钟前
如何在 Vue 项目的 template 中使用 JSX
前端·javascript·vue.js
布列瑟农的星空4 分钟前
大话设计模式——多应用实例下的IOC隔离
前端·后端·架构
EndingCoder8 分钟前
安装与环境搭建:准备你的 Electron 开发环境
前端·javascript·electron·前端框架
蓝银草同学24 分钟前
前端离线应用基石:深入浅出 IndexedDB 完整指南
前端·indexeddb
龙在天35 分钟前
什么是SourceMap?有什么作用?
前端
雪中何以赠君别39 分钟前
Vue 2 与 Vue 3 双向绑定 (v-model) 区别详解
前端·javascript·vue.js
林太白41 分钟前
Vue3-ElementPlus使用
前端·javascript·vue.js
Juchecar1 小时前
npm、pnpm、yarn 是什么?该用哪个?怎么用?如何迁移?
前端·node.js
CYRUS_STUDIO1 小时前
Miniconda 全攻略:优雅管理你的 Python 环境
前端·后端·python
学不动学不明白1 小时前
ECharts 为visualMap视觉映射添加自适应外边框
前端