node中间件使用踩坑路

起因

在请求某个页面的时候,会在query中,携带一个ticket,在显示这个页面之前,前端回去判断这个票据是否有效,如果是非法或无效的,则直接回退到上一个页面

经过

  • 在前端,架了一个用node写的中间层,在这个中间层,我是用了express提供的中间件app.use()监听所有路过的请求
1
2
3
4
5
6
const express = require('express')
const app = express()

app.use(function(req, res, next) {
// 所有的请求都会从这里过
})

  • 我们首先要去判断请求是否是我们要处理的
1
2
3
4
5
6
7
8
app.use(function(req, res, next) {
if (req.url.includes('personalInfo')) {
// 如果是我们要处理的请求,在这里做处理
} else {
// 否则就去执行下一个中间件
next()
}
})

  • 如果是我们要处理的,进入内部流程,我们要去判断携带的ticket是否有效
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const searchStr = req.url.split('?')[1]
const searchArr = searchStr.split('&')
let ticket
searchArr.forEach((item) => {
if (item.includes('ticket')) {
ticket = item.split('=')[1]
}
})
checkToken(ticket, (info) => {
const response = JSON.parse(info)
if (response.code === 1000) {
next()
} else {
res.redirect('back')
}
})

  • 这个时候,一个关键的问题出现了,checkToken这个是去校验ticket是否有效的请求,所以我们要在中间件内去请求后端,这是困扰我的一个大问题,在node里向服务器发起一个get请求
1
2
3
4
5
6
7
8
9
10
11
12
13
14
const http = require('http')
// 向服务端发起请求验证token
function checkToken(data, callBack) {
http
.get(
`${process.env.BASE_URL}/xxx/${data}`,
function(res) {
// 处理成功的回调
}
)
.on('error', function(e) {
callBack(e)
})
}

  • 经过研究,上一步,我们已经在node层向服务器发起了一个get请求了,也拿到了对应的响应,但是问题又来了,这个请求成功回调回来的res是一个非常复杂的东西,我如何取到服务器返回的响应主体呢?又经过不断的突破,我终于找到了
1
2
3
4
5
6
let repData = ''
res.on('data', function(data) {
// 通过这种方式去获取响应主体的内容并转成字符串
repData = data.toString()
callBack(repData)
})

  • 这下最主要的问题都解决了,我们来看完整的代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
const http = require('http')
const express = require('express')
const app = express()
// 添加中间件,做token异常处理
app.use(function(req, res, next) {
if (req.url.includes('personalInfo')) {
const searchStr = req.url.split('?')[1]
const searchArr = searchStr.split('&')
let ticket
searchArr.forEach((item) => {
if (item.includes('ticket')) {
ticket = item.split('=')[1]
}
})
checkToken(ticket, (info) => {
const response = JSON.parse(info)
if (response.code === 1000) {
next()
} else {
// 如果服务器不返回1000就是有问题的ticket,直接回退到上一个页面
res.redirect('back')
}
})
} else {
next()
}
})

// 向服务端发起请求验证token
function checkToken(data, callBack) {
http
.get(
`${process.env.BASE_URL}/api/v1/delta/user/collect/moreInfo/check/${data}`,
function(res) {
let repData = ''
res.on('data', function(data) {
repData = data.toString()
callBack(repData)
})
}
)
.on('error', function(e) {
callBack(e)
})
}