Express路由
路由的概念:
在Express 中,路由指的是客户端的请求与服务器处理函数之间的映射关系。
Express 中的路由分3部分组成,分别是请求的类型、请求的URL地址、处理函数
匹配过程:
每当一个请求到达服务器之后,需要先经过路由的匹配,只有匹配成功之后,才会调用对应的处理函数。
在匹配时,会按照路由的顺序进行匹配,如果请求类型和请求的URL同时匹配成功,则Express 会将这次请求,转交给对应的function 函数进行处理。
模块化路由
创建一个路由模块,即js文件
const express=require('express')
//创建路由对象
const router=express.Router()
//挂载具体的路由
router.get('/user/list',(req,res)=>{
res.send('get user list')
})
router.post('/user/add',(req,res)=>{
res.send('add new user')
})
//向外导出路由模块
module.exports=router
在服务器中导入上述自定义模块,即可正常使用
const express=require('express')
const app=express()
//导入路由模块
const router=require('./router')
//注册路由模块
app.use(router)
app.listen(80,()=>{
console.log('http:///127.0.0.1')
})
//注意:app.use()函数的作用,就是来注册全局中间件
如果需要为路由模块挂载前缀,方式如下:
app.use('/api',router)
Express中间件
当一个请求到达Express的服务器之后,可以连续调用多个中间件,从而对这次请求进行预处理。
注意:中间件函数的形参列表中,必须包含next 参数。而路由处理函数中只包含req和res。
next函数的作用:next函数是实现多个中间件连续调用的关键,它表示把流转关系转交给下一个中间件或路由。
创建一个中间件函数
示例如下:
const express=require('express')
const app=express()
const mw=function(req,res,next){
console.log('这是最简单的中间件函数')
//把流转关系,转交给下一个中间件函数或路由
next()
}
app.listen(80,()=>{
console.log('http://127.0.0.1')
})
全局生效的中间件
客户端发起的任何请求,到达服务器之后,都会触发的中间件,叫做全局生效的中间件。
通过调用app.use(中间件函数),即可定义一个全局生效的中间件,示例代码如下:
//将mw注册为全局生效的中间件
app.use(mw)
注册全局中间件的简化形式:
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()
})
app.get('/',(req,res)=>{
res.send('home page'+req.startTime)
})
app.get('/user',(req,res)=>{
res.send('user 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('/',(req,res)=>{
res.send('home page')
})
app.listen(80,()=>{
console.log('http://127.0.0.1')
})
定义局部生效的中间件
const express=require('express')
const app=express()
//定义中间件函数
const mw1=(req,res,next)=>{
console.log('调用了局部生效的中间价')
next()
}
//创建路由
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.urlencoded 这样的中间件,来解析POST 提交到服务器的表单数据。
实现步骤:
- 定义中间件
- 监听req的data事件
- 监听req的end事件
- 使用querystring模块解析请求体数据
- 将解析出来的数据对象挂载为req.body
- 将自定义中间件封装为模块
二、代码实现
const express=require('express')
const app=express()
//导入node.js中内置的querystring模块
const qs=require('querystring')
//这是用来解析表单数据的中间件
app.use((req,res,next)=>{
//1、定义一个str字符串,专门用来储存客户端发过来的请求
let str=''
//2、监听req的data事件
req.on('data',(chunk)=>{
str+=chunk
})
//3、监听req中的end事件
req.on('end',()=>{
// console.log(str)
const body=qs.parse(str)
req.body=body
next()
})
})
app.get('/',(req,res)=>{
res.send("ok")
})
app.listen(80,()=>{
console.log('http://127.0.0.1')
})
使用Express编写接口
接口代码示例:
const express=require('express')
const app=express()
//配置解析表单数据的中间件
app.use(express.urlencoded({extended:false}))
//导入路由模块
const router=require('./apiRputer')
//把路由模块注册到app上
app.use('/api',router)
app.listen(80,()=>{
console.log('http://127.0.0.1')
})
编写GET接口
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//需要响应给客户端的数据
})
})
module.exports=router
编写POST接口
const express=require('express')
const router=express.Router()
//在这里挂载对应的路由
router.post('/post',(req,res)=>{
//通过req.body获取请求体中包含的url-encoded格式的数据
const body=req.body
//调用res.send方法,向客户端响应结果
res.send({
status:0,
msg:'GET请求成功',
data:body
})
})
module.exports=router
CORS跨域资源共享
cors 是Express的一个第三方中间件。通过安装和配置cors中间件,可以很方便地解决跨域问题。
CORS (Cross-Origin Resource Sharing,跨域资源共享)由一系列HTTP响应头组成,这些HTTP响应头决定浏览器是否阻止前端JS代码跨域获取资源。
浏览器的同源安全策略默认会随让网页“跨域”获取资源。但如果接口服务器配置了CORS相关的 HTTP响应头,就可以解除浏览器端的跨域访问限制。
注意:
- CORS主要在服务器端进行配置。客户端浏览器无须做任何额外的配置,即可请求开启了CORS的接口。
- CORS在浏览器中有兼容性。只有支持XMLHttpRequest Level2的浏览器,才能正常访问开启了CORS的服务器接口(例如:IE10+、Chrome4+、FireFox3.5+)。