node笔记05——Nodejs学习之Express中间件与接口的编写,GET和POST接口的编写和案例演示。

认识express

express是基于Node.js平台的web开发框架

作用和Node.js内置的http模块类似,是专门用来创建Web服务器的。

本质上Express就是一个npm的第三方包提供了快速创建Web服务器的便捷方法。

中文官网:expressjs.com.cn

express的作用:快速方便的创建 Web网站服务器和 API 接口服务器

express的基本使用

一、下载express包 npm i express@4.17.1

二、创建基本的web服务器

// 导入express
const express = require('express')

// 创建web服务器
const app = express()

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

监听 GET、POST 请求

1、get请求一般用来请求获取数据、post请求一般作为发送数据到后台,传递数据,创建数据

2、get请求也可以传参到后台,但是传递的参数则显示在地址栏,安全性低,且参数的长度也有限制(2048字符)、 post请求则是将传递的参数放在request body中,不会在地址栏显示,安全性比get请求高,参数没有长度限制

3、get请求刷新浏览器或者回退没有影响、post请求则会重新请求一遍

4、get请求可以被缓存,也会保留在浏览器的历史记录中、post请求不会被缓存,也不好保留在浏览器的历史记录中

5、get请求通常是通过url地址请求、post常见的则是form表单请求


参数一、客户端请求的URL地址 参数二、请求队形的处理函数

req 请求对象 res 响应对象

通过 app.post( )方法监听客户端POST请求。

通过 app.get( )方法可以监听客户端的GET请求。

把内容响应给客户端

通过 res.send( )方法,可以把处理好的内容发送给客户端

// 监听客户的 GET 和 POST 请求,并向客户端响应具体内容
app.get('/user',(req,res)=>{
    // 调用res.send方法向客户端响应一个JSON对象
    res.send( {name: 'zhangsan',age: 20, gender: '男'})
})
app.post('/user',(req,res)=>{
    // 调用res.send向客户端响应一个文本字符串
    res.send('请求成功')
})

获取 URL 中携带的查询参数

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

app.get('/',(req,res)=>{
    // 通过 req.query 可以获取到客户端发送过来的查询参数
    // 默认情况下req.query是空对象
    console.log(req.query)
    res.send(req.query)
})

获取URL中的动态参数

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

// 这里的 :id是一个动态的参数
app.get('/user/:id',(req,res)=>{
    // req.params 是动态匹配到的 URL 参数,默认也是一个空对象
    console.log(req.params)
    res.send(req.params)
})

向 http://127.0.0.1/user/ABCD发送请求后得到响应:

{
	"id": "ABCD"
}

express.static 托管静态资源

express.static( )方法可以方便的创建一个静态资源服务器。 通过如下代码可以将public目录下的文件对外开放

app.use(express.static('public'))

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

**想要托管多个静态资源目录,则多次调佣express.static( )即可

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

// 调用 express.static( ) 方法快速对外提供静态资源
// 传入文件目录位置
app.use(express.static('./clock'))
app.use(express.static('./files'))

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

静态资源访问路径之前挂载前缀

app.use('/abc',express.static('./files')) :只需要在express.static 前面添加一个前缀即可

学习nodemon工具

该工具可以监听Node.js项目的代码,如果项目的代码发生了修改,该工具会自动重启项目,更方便开发和调试。

安装nodemon npm install -g nodmon

安装nodemon工具后,启动项目的方法:nodemon app.js

Express路由

路由的概念:就是映射关系。在express中路由指的是客户端的请求与服务器处理函数之间的映射关系

express中的路子分三部分组成

  • 请求的类型(METHOD):GET或者POST
  • 请求的地址PATH
  • 处理函数HANDLER

app.METHOD(PATH,HANDLER)

一个简单的路由的例子

app.get('/',function(req,res){
	res.send('hello,world')
})
app.post('/',(req,res)=>{
	res.send('got a POST request')
})

路由的匹配过程

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

会按照路由的顺序进行匹配。

如果请求类型和请求的URL同事匹配Express才会将这次请求转交给对应的function进行处理。

模块化路由

Express不建议将路由直接挂载到app上。为了方便对路由进行模块化的管理,一般将路由抽离为单独的模块

一、创建路由模块对应的 .js 文件

二、调用 **express.Router( )**创建路由对象

三、向路由对象上挂载具体的路由

四、使用 module.exports向外共享路由对象

五、使用 app.use( )函数注册路由模块

创建路由模块

// 这是一个路由模块
//1、导入express
const express = require('express')

//2、创建路由对象
const router = express.Router()

//3、挂载具体的路由
router.get('/user/list',(req,res)=>{
    res.send('get user list')
})
router.post('/user/add',(req,res)=>{
    res.send('add new user')
})

//4、向外到处路由对象
module.exports = router

注册路由模块

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

// 导入路由模块
const router = require('./05router')
// 注册路由模块
//app.use(router)
app.use('/api',router)// 统一添加访问前缀。

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

app.use( )函数的作用就是用来注册全局中间件的。

express中间件

中间件指的就是业务处理过程中的中间处理环节,一般有输入与输出。

中间件是一个可访问请求对象(req)和响应对象(res)以及(next)的函数

中间件调用流程

当一个请求到达Express的服务器,可能连续调用多个中间件,对该请求进行预处理

请求=>中间件处理next(中间件处理2 )=>next(中间件处理n)=>next(处理完毕)=>路由响应到客户端

中间件的格式

中间件本质上就是一个Function处理函数:格式如下:

app.get('/',function(req,res,next){
	next( )
})

中间件的形参列表中必须包含next形参

next函数的作用

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

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

// 定义一个中间件
const mw = (req,res,next)=>{
    console.log("这是一个简单的中间件函数")
    // 把流转关系转交给下一个中间件或路由
    next()
}
app.listen(80,()=>{
    console.log("http:127.0.0.1")
})

全局生效的中间件

客户端发起任何请求,到达服务器之后都会被触发的中间件,即为全局生效中间件

通过 app.use(中间件函数),即可定义一个全局生效中间件

示例代码:

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

// 定义一个中间件
const mw = (req,res,next)=>{
    console.log("这是一个简单的中间件函数")
    // 把流转关系转交给下一个中间件或路由
    next()
}
// 将 mw 注册为全局生效的中间件
app.use(mw)

app.get('/',(req,res)=>{
    console.log('调用了 / 路由')
    res.send('Home page.')
})
app.get('/user',(req,res)=>{
    console.log('调用了 /user 路由')
    res.send('uese page.')
})
// 启动服务器
app.listen(80,()=>{
    console.log("http:127.0.0.1")
})

全局生效中间件的简化形式

app.use((req,res,next)=>{
  console.log('这是一个简单的中间件函数的简写')
  next()
})

中间件的作用

由于多个中间件之间可以共享一份req和res,所以我们可以再上有的中间件中统一为 req 或 res 对象添加自定义的属性或方法,宫下游的中间件或路由进行使用。

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

app.use((req,res,next)=>{
    // 获取到请求到达服务器的事件
    const time = Date.now()
    // 为req对象挂载自定义属性,从而把时间共享到后面所有的路由
    req.startTime = time
    next()
  })

const a = app.get('/',(req,res)=>{
    res.send('Home page.' + req.startTime)
})
app.get('/user',(req,res)=>{
    res.send('uese page.' +req.startTime)
})

// 启动服务器
app.listen(80,()=>{
    console.log("http:127.0.0.1")
})

定义多个全局中间件

可以使用 app.use( ) 定义多个全局中间件。客户端请求到达服务器之后,会按照定义的先后顺序依次执行

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

// 定义了第一个全局中间件
app.use((req,res,next)=>{
    console.log('调用了第一个全局中间件')
    next()
})
// 定义了第二个全局中间件
app.use((req,res,next)=>{
    console.log('调用了第二个全局中间件')
    next()
})
// 定义一个路由,请求路由后先调用中间件
app.get('/user',(req,res)=>{
    console.log('最后进入了路由')
    res.send('User page.')
})

app.listen(80,()=>{
    console.log("http://127.0.0.1")
})

局部生效的中间件

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

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

// 定义中间件
const mw1 = (req,res,next)=>{
    console.log('调用了局部生效的中间件')
    next()
}
// 创建路由
// mw1中间件只会在当前路由中生效
app.get('/',mw1,(req,res)=>{ res.send('Home page.') })
app.get('/user',(req,res)=>{ res.send('User page.') })

app.listen(80,()=>{
    console.log("http://127.0.0.1")
})

定义多个局部中间件的方法

app.get('/',mw1,mw2,(req,res)=>{ res.send('Home page.') })
app.get('/',[mw1,mw2],(req,res)=>{ res.send('Home page.') })

Express中间件初体验

中间件的使用注意事项

  • 一定要在路由之前注册中间件
  • 客户端发送过来的请求可以连续调用多个中间件进行处理
  • 执行文中间件的业务代码后一定要调用next( )函数
  • 在调用完 next( )之后,尽量不要再写额外代码,防止逻辑混乱
  • 连续调用多个中间件,多个中间件之间共享req和res

中间件的分类(五大类)

一、应用级中间件

通过 app.use( ) 或 app.get( ) 或者 app.post( ) 绑定到实例上的中间件

二、路由级中间件

绑定到 express.Router( ) 实例上的中间件。

三、错误级别中间件

作用是捕获项目中可能会发生的异常错误,从而防止项目崩溃、错误级别中间件必须有四个形参: (err,req,res,next)

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

app.get('/',(req,res)=>{
    // 认为的制造一个错误
    throw new Error('服务器内部发生错误')
    res.send('Home page.')
})
// 定义错误级别中间件来捕获整个项目的异常错误从而防止程序崩溃
app.use((err,req,res,next)=>{
    console.log('发生了错误'+err.message)
    res.send('Error:'+err.message)
})


app.listen(80,()=>{
    console.log("http://127.0.0.1")
})

注意:错误级别中间件一定要注册到所有路由之后

四、Expreww内置中间件

Express内置了三个常用中间件

1、express.static:快速托管静态资源的内置中间件:HTML/CSS/图片等。

2、express.json:解析 JSON 格式的请求体数据。4.16.0+node可用

app.use(express.json())

3、express.urlencodes:解析 URL-encoded 格式的请求数据。4.16.0+node可用,该中间件就是基于第三方body-parser 封装出来的。

app.use(express.urlencoded( { extended: false} ) )

示例:

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

// 通过express.json() 全局中间件解析表单中JSON数据
app.use(express.json())
// 通过express.urlencoded() 中间件来解析表单中的 url-encoded 格式的数据。
app.use(express.urlencoded( { extended: false} ))

app.post('/user',(req,res)=>{
    // 服务器可以使用 req.body属性接收客户端发送的请求体数据
    // 但没有配置表单解析数据的中间件,req.body 默认等于 undefined
    console.log(req.body)
    res.send('Ok!')
})
app.post('/book',(req,res)=>{
    // 通过 req.body 获取 url-encoded格式数据
    console.log(req.body)
    res.send('Book!')
})

app.listen(80,()=>{
    console.log("http://127.0.0.1")
})
五、第三方中间件

非 Express 内置的,第三方开发出来的中间件。可以按需下载,如 body-parser 中间件

1、安装: npm i body-parser 2、导入 3、注册使用

const express = require('express')
const app = express()
// 配置解析表单数据的中间件
const parser =  require('body-parser')
// 注册该中间件
app.use(parser.urlencoded( { extended: false }))

app.post('/user',(req,res)=>{
    // 未配置解析中间件默认req.body值为undefined
    console.log(req.body)
    res.send('Ok!')
})

app.listen(80,()=>{
    console.log("http:127.0.0.1")
})

案例:尝试自定义一个中间件

const express = require('express')
// 导入 querystringify模块,该内置模块其提供的parse()可以将查询字符串解析成对象格式
const qs = require('querystringify')
const app = express()

app.use((req,res,next)=>{
    // 定义存储数据的字符串
    let str = ''
    // 监听req的dat事件
    req.on('data',(chunk)=>{
        str += chunk
    })
    // 监听req的end事件
    req.on('end',(chunk)=>{
        // 把字符串格式的请求数据解析成对象
        req.body = qs.parse(str)
        next()
    })
})

// 路由
app.post('/user',(req,res)=>{
    res.send(req.body)
})


// 启动服务器
app.listen(80,()=>{
    console.log("http:127.0.0.1")
})
还可以将自定义中间件封装成模块
const qs = require('querystringify')

const bodyParser = (req,res,next)=>{
    // 定义存储数据的字符串
    let str = ''
    // 监听req的dat事件
    req.on('data',(chunk)=>{
        str += chunk
    })
    // 监听req的end事件
    req.on('end',(chunk)=>{
        // 把字符串格式的请求数据解析成对象
        req.body = qs.parse(str)
        next()
    })
}

module.exports = bodyParser

使用express写接口

创建API路由模块

//创建路由模块
const express = require('express')
const router = express.Router()
//在这里挂载对应的路由

module.exports = router

--------------------------------------

const express = require('express')
const app = express()
// 导入路由模块
const router = require('./19APIrouter')

// 注册路由模块到app
app.use('/api',router)


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

编写 GET 接口与 POST 接口

const express = require('express')
const router = express.Router()

//在这里挂载对应的路由
router.get('/get',(req,res)=>{
    // 通过 req.query 获取客户端,通过查询字符串,发送到服务器的数据
    const query = req.query
    //调用 res.send() 方法向客户端响应处理结果
    res.send({
        status:0, // 0表示处理成功,1表示处理失败
        msg:'GET 请求成功', // 状态描述
        data: query // 客户端的数据
    })
})

//在这里挂载对应的路由
router.post('/post',(req,res)=>{
    // 通过 req.body 获取请求体中包含 url-encoded 格式的数据
    const body = req.body
    //调用 res.send() 方法向客户端响应处理结果
    res.send({
        status:0, // 0表示处理成功,1表示处理失败
        msg:'POST 请求成功', // 状态描述
        data: body // 客户端的数据
    })
})

module.exports = router

接口的跨域问题

以上的GET和POST接口存在跨域的问题

解决方案:

一、CORS(主流方案)

二、JSPNP(只支持GET请求)

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值