Express 指北☞| 青训营笔记

202 阅读6分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第18天

(概述:认识Express、Express路由、Express中间件、使用Express写接口)

认识Express

Expres是基于Node.js平台,快速、开放、极简的Web开发框架。

Express的作用和Node.js内置的http模块类似(axios和ajax的关系),是专门用来创建Web服务器的

**本质:**一个npm的第三方包,提供了快速创建Web服务器的方法。

www.expressjs.com.cn/

Express能做什么?

使用Express,我们可以方便快速创建Web网站服务器和API接口服务器。

Express基本使用

npm i express@4.17.1
//创建基本的Web服务器
const express = require('express')

const app = express()

app.listen(82, () => {
    console.log('express server running at http://127.0.0.1:82')
})

监听GET/POST请求

// 参数1:客户端请求的URL地址
// 参数2:请求对应的处理函数 req:请求对象;res:响应对象
app.get('请求URL',function(req,res){/*处理函数*/})

app.POST('请求URL',function(req,res){/*处理函数*/})

把内容响应给客户端

app.get('/user',(req,res)=>{
    res.send({name:'zx',age:20,gender:'男'})
})

获取URL中携带的查询参数

通过res.query对象,可以访问到客户端通过查询字符串的形式,发送到服务器的参数。

app.get('/',(req,res)=>{
    console.log(res.query)
})

获取URL中携带的动态参数

通过res.params对象,可以访问到URL中通过:匹配到的动态参数。

app.get('/user/:id',(req,res)=>{
    console.log(res.params)
})

托管静态资源

通过express.static(),我们可以创建一个静态资源服务器

app.use(express.static('public')) //public文件夹
//http://localhost:3000/images/big.jpg

app.use('/public',express.static('public')) //挂载路径前缀
//http://localhost:3000/public/images/big.jpg

//托管多个静态资源目录
app.use(express.static('public')) 
app.use(express.static('files')) //同名资源顺序查找

注意:存放静态文件的目录名不会出现在URL中。

工具nodemon

这个工具可以监听项目文件的变动,自动重启项目(热加载)。

npm i -g nodemon
node app.js
nodemon app.js

Express路由

Express中的路由

在Express中,路由是指客户端的请求服务器处理函数之间的映射关系

由三部分组成:请求的类型、请求的地址、处理函数

app.METHOD(PATH,HANDLER)
app.get('/user',(req,res)=>{
    res.send({name:'zx',age:20,gender:'男'})
})

路由的匹配

每当一个请求到的服务器之后,需要先经过路由的匹配,只有匹配成功后,才会调用对应的处理函数。

模块化路由

你当然可以像上面那样将路由挂载到app实例上,但随着路由的增多,文件体积会越来越大,不方便管理。推荐将路由抽离为单独的模块

  1. 创建路由模块对应的js文件
  2. 调用express.Router()函数创建路由对象
  3. 向路由对象上挂载具体的路由
  4. 使用module.exports向外共享路由对象
  5. 使用app.use函数注册路由模块
const express = require('express')
const app = express()

const router = require('./06Router')
// console.log(router)
app.use(router)
//app.use函数是用来注册全局中间件的
app.listen(82, () => {
    console.log('express server running at http://127.0.0.1:82')
})
//路由模块
var express = require('express')
var router = express.Router()

router.get('/user', (req, res) => {
    res.send({ name: 'zx', age: 20, gender: '男' })
})

router.post('/user/add', (req, res) => {
    res.send('Add new user')
})

module.exports = router
app.use('api',router)//添加前缀

Express中间件

什么是中间件?

中间件(Middleware),特指业务流程的中间处理环节。当一个请求到达Express的服务器后,可以连续调用多个中间件,从而对这次请求进行预处理

Express中间件,本质上是一个function处理函数,格式如下:

image.png 注意:中间件的形参列表中,必须包含next参数,而路由处理函数只包含reqres

next函数的作用

next函数是实现多个中间件连续调用的关键,它表示把流转关系转交给下一个中间件路由

中间件的作用

多个中间件之间,共享同一份 reqres。基于这样的特性,我们可以在上游的中间件中,统一为 reqres 对象添加自定义的属性或方法,供下游的中间件或路由进行使用。

全局中间件

客户端发起的任何请求,到达服务器之后,都会触发的中间件。通过app.use(中间件函数),即可定义一个全局生效的中间件

const express = require('express')
const app = express()

const mw=function(req,res,next){
    console.log('这是最简单的中间件函数!')
    next()//把流转关系,转交给中间件或路由
}
app.use(mw)

app.listen(82, () => {
    console.log('express server running at http://127.0.0.1:82')
})
//简写形式
app.use((req,res,next)=>{
    console.log('这是最简单的中间件函数!')
    next()//把流转关系,转交给中间件或路由
})

局部中间件

不使用app.use(中间件函数)定义的中间件,叫做局部生效的中间件。

const express = require('express')
const app = express()

const mw=function(req,res,next){
    console.log('这是最简单的中间件函数!')
    next()//把流转关系,转交给中间件或路由
}
app.get('/user',mw,(req,res)=>{
    res.send({name:'zx',age:20,gender:'男'})
})

app.listen(82, () => {
    console.log('express server running at http://127.0.0.1:82')
})

注意事项

  • 在路由之前注册中间件
  • 客户端发送过来的请求,可以连续调用多个中间件进行处理
  • 执行完中间件的业务代码,不要忘记调用next()函数
  • 调用完next()函数,不要在写额外代码
  • 连续调用多个中间件,共享 reqres对象

中间件的分类

  • 应用级别的中间件:绑定到app实例上的中间件。
  • 路由级别的中间件:绑定到express.Router()实例上的中间件。
  • 错误级别的中间件:专门捕获项目中的异常错误,防止项目异常崩溃。(注册在路由之后)
  • Express内置的中间:express.static()express.json()express.urlencoded()
// 配置解析 application/json 格式数据的内置中间件 不配置打印undefined
app.use(express .json())
// 配置解析 application/x-ww-form-urlencoded 格式数据的内置中间件
app.use(express.urlencoded({ extended: false }))
  • 第三方的中间件

使用Express写接口

//路由模块
var express = require('express')
var router = express.Router()

//GET接口
router.get('/get', (req, res) => {
    const query = req.query
    res.send({
        status: 0,
        msg: 'GET请求成功!',
        data: query,
    })
})
//POST接口
router.post('/post', (req, res) => {
    const body = req.body
    res.send({
        status: 0,
        msg: 'POST请求成功!',
        data: body,
    })
})

module.exports = router
//创建基本的服务器
//导入express
const express = require('express')
//创建服务器实例
const app = express()

//配置解析表单数据的中间件
app.use(express.urlencoded({ extended: false }))

//创建API路由模块
const router = require('./06Router')
app.use('/api', router)

//启动服务器
app.listen(82, () => {
    console.log('express server running at http://127.0.0.1:82')
})

解决跨域问题

CORS方案

CORS(Cross-Origin Resource Sharing,跨域资源共享)是Express的一个第三方中间件。通过安装和配置CORS中间件,可以很方便地解决跨域问题。使用步骤分为如下3步:

npm install cors//安装中间件
const cors = require('cors')//导入中间件
app.use(cors()) //配置中间件

CORS由一系列HTTP响应头组成,这些HTTP响应头决定浏览器是否阻止前端JS代码跨域获取资源。浏览器的同远安全策略默认会阻止网页跨域获取资源,但接口服务器配置了CORS相关的HTTP响应头,就可以解除浏览器端的跨域访问限制

注意:

  • CORS只要在服务器端进行配置,客户端无需进行如何额外的配置。
  • CORS在浏览器中有兼容性,只有支持XHR2的浏览器才能正常访问开启了CORS的服务器接口。

响应头部:

Access-Control-Allow-Origin//指定允许访问该资源的外域URL

Access-Control-Allow-Headers//向客户端发送额外请求头信息

Access-Control-Allow-Methods//指明实际请求所允许使用的HTTP方法

分类:

  • 简单请求

  • 预检请求:在正式通信之前,浏览器会先发送OPTION请求进行预检,以获知服务器是否允许该实际请求

JSONP方案(只支持GET请求)