使用node反向代理接口改造旧项目
使用node搭建代理服务器提升旧项目的开发体验
# 前情说明
最近公司分配了一个旧系统维护任务,该系统用的是 springBoot,前后端没有分离,前端使用的是 jQuery+easyUI,并且和后端代码在一个总目录下,前端代码托管在后端起的静态服务下,由于前端对 SpringBoot 不熟,之前做修改都是前端代码改完之后用 maven 编译一下来查看,修改完之后又得重启下服务,并且还只能用本地服务调试。这也太影响效率了,虽然也不是不能开发,但是对于习惯了webpack的热更新的我来说,这简直就像回到了解放前,鉴于开发任务也不是很紧,对项目一番分析,发现前后端完全可以分离,转发一下请求服务的地址就行,跟一直做得 vue.config.js 里的 proxyTable 是一个意思。
本来准备用 NGINX 来配置的,然鹅我对 NGINX 也是只了解皮毛,网上的教程看的也一知半解,只好用 Node 来实现了,至少我司的前端还能看懂。说干就干,一番搜索下来,使用express
起一个简单的静态服务,然后使用http-proxy-middleware
代理下接口请求就可以了.
# 匹配规则的设置
http-proxy-middleware
文档还是比较清晰的,看着文档也能配置出来一些,主要是接口匹配规则上,之前接口代理一般做的都是类似 将以/api
开头的请求转发到测试服务器,然而这次碰到的是需要将以.do
结尾的请求转发到目标服务器上,以.do
结尾的规则是*.do
,但是前面的路径咋配置呢,在这里走了一些弯路,由于不清楚前面路径的配置,我使用了pathRewrite
方法,在里面对 path 进行判断来进行转发,虽然也可行,但是后面增加了需要代理的规则就得修改判断条件,比较麻烦。经过一段时间的摸索,发现其实两个星号就是代表着任意,**/*.do
就代表着以.do
结尾的请求,这样匹配规则就完成了。
# cookie 的转发
在处理中还发现我们的接口请求头中使用了 cookie 进行接口校验,每次请求都得带着校验信息。http-proxy-middleware
配置项里提供了 request 和 response 相关处理函数,我们把服务器返回的 cookie 复制到代理请求上就可以了,简单代码如下:
var cookie = null
var options = {
onProxyReq(proxyReq) {
// 将本地请求的头信息复制一遍给代理。
// 包含cookie信息,这样就能用登录后的cookie请求相关资源
if (cookie) {
proxyReq.setHeader('cookie', cookie)
}
},
onProxyRes(proxyRes) {
// 将服务器返回的头信息,复制一遍给本地请求的响应。
// 这样就能实现 执行完登录后,本地的返回请求中也有相关cookie,从而实现登录功能代理。
var proxyCookie = proxyRes.headers['set-cookie']
if (proxyCookie) {
cookie = proxyCookie
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 最终配置如下
const express = require('express')
const { createProxyMiddleware } = require('http-proxy-middleware')
const args = process.argv.splice(2)
// 本地调试的时候target设置为本地,默认为远程测试服务器
var target = 'http://X.X.X.X:XX'
if (args.length > 0 && args.includes('localhost')) {
target = 'http://localhost:XX'
}
// 接口代理
var cookie = null
const options = {
target,
changeOrigin: true, //处理跨域
onProxyReq(proxyReq) {
// 将本地请求的头信息复制一遍给代理。
// 包含cookie信息,这样就能用登录后的cookie请求相关资源
if (cookie) {
proxyReq.setHeader('cookie', cookie)
}
},
onProxyRes(proxyRes) {
// 将服务器返回的头信息,复制一遍给本地请求的响应。
// 这样就能实现 执行完登录后,本地的返回请求中也有相关cookie,从而实现登录功能代理。
var proxyCookie = proxyRes.headers['set-cookie']
if (proxyCookie) {
cookie = proxyCookie
}
},
logLevel: 'debug' //string, 可选['debug', 'info', 'warn', 'error', 'silent'],默认值'info'
}
// 代理规则:https://github.com/chimurai/http-proxy-middleware#readme
const pathRule = ['**/*.do', '**/getAllRoles', '/boot/OA/**']
const apiProxy = createProxyMiddleware(pathRule, options)
const app = express()
// boot 的static前端目录路径,加一个/boot的虚拟地址因为前端中有些写了根据部署路径跳转
app.use('/boot', express.static('xxx/src/main/resources/static'))
app.use('/', apiProxy)
app.listen(3000, () => {
console.log(`server is running on port ${3000}`)
})
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
46
47
48
如果后面还要需要代理的接口,直接往pathRule数组中添加代理规则就可以了。
# 总结
这里简单使用了 http-proxy-middleware
对一些接口进行请求的转发,通过这不到50行的代码,我们把前后端开发解耦了,前端开发不再依赖于后端起的服务,我们可以随意的调整刷新就可以看到效果,虽然代码很简单,但是对开发效率还是有了一定的的提高,分享给同组的小伙伴后他们也用的很开心。工作上的事情能改进的还是应该去尝试一下,而不是大家都这么开发的,我为什么要去试试另外的方式呢,从来如此的,便对么?虽然是花费了你的时间,但是提高了团队的效率,这也算团队基建的一种吧。
后续也想集成webpack的HMR服务,但是一直没成功,鉴于维护工作已完成也就没有动力再去做这个了。