# 简介
基于 UView 内置的请求框架luch-request (opens new window)做二次封装
# 功能
- 基础请求类型封装: get、post、put、delete [✅]
- 集成请求代理功能 [✅]
- 无感刷新 token 封装 [x]
- 自定义后端请求 code 报错信息 [x]
# 回顾
在上一篇中,我们实现了基础的请求功能,但是在实际的开发过程中我们会发现,在小程序、App 平台请求需要带请求域名前缀,不像 h5 平台上会通过 webpack.devServer.proxy 实现接口代理,这会给我们跨端开发造成障碍,为了解决这个问题,本章将参考 http-proxy-middleware 中 getTargetFromProxyTable 函数,基于 proxyTable 实现代理功能
# 先实现 webpack.devServer.proxy
项目根目录下创建 webpack 文件夹,新建 proxy.js 文件
const customProxy = {}
const urls = {
devURL: {
source1: 'http://127.0.0.1:7002',
source2: 'http://dev.source2.com'
},
testURL: {
source1: 'http://test.source1.com',
source2: 'http://test.source2.com'
},
prodURL: {
source1: 'http://prod.source1.com',
source2: 'http://prod.source2.com'
}
}
// 环境
const envs = ['dev', 'test', 'prod']
// 分布式部署服务路径
const services = ['source1', 'source2']
// 构建基础项目代理
function generateProxy() {
return envs.reduce((envAcc, env) => {
return services.reduce((serviceAcc, service) => {
const basePath = `/${env}/${service}`
const rewriteKey = `^${basePath}`
serviceAcc[basePath] = {
target: urls[`${env}URL`][service],
pathRewrite: {
[rewriteKey]: ''
}
}
return serviceAcc
}, envAcc)
}, {})
}
module.exports = {
...customProxy,
...generateProxy()
}
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
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
# 预定义部分参数
项目根目录新建 index.js,主要是为了方便后期通过自动化脚本进行不同环境打包
// 需要与根目录下的/webpack/proxy中的envs配置保持一致
export const envEnums = {
dev: 'dev',
test: 'test',
prod: 'prod'
}
export const env = envEnums.dev
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
在 src 目录下创建 constant 文件夹,新建 index.js 文件,
// 需要与根目录下的/webpack/proxy中的services配置保持一致
export const serverTypeEnums = {
source1: 'source1',
source2: 'source2'
}
export const serverTypeValues = Object.keys(serverTypeEnums)
export const isBuild = process.env.NODE_ENV === 'production'
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# 根据接口 url 获取重定向的请求地址
import proxy from '../../webpack/proxy'
const getTargetFromProxy = (path = '') => {
let result
for (const [key, value] of Object.entries(proxy)) {
if (path.indexOf(key) > -1) {
result = value
break
}
}
const origin = result.target
let realPath = path
if (result.pathRewrite) {
for (const [key, value] of Object.entries(result.pathRewrite)) {
const reg = new RegExp(key)
if (reg.test(path)) {
realPath = realPath.replace(reg, value)
break
}
}
}
return origin + realPath
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 调整 service 函数主体
// ****
// 缓存当前请求的id
const currentId = id
const envPath = isBuild ? '' : `/${env}/${serverTypeEnums[serverType]}`
let origin = isBuild ? '' : ''
let requestURL = origin + envPath + url
// 小程序、app需要带源地址
// #ifdef MP-WEIXIN || APP-PLUS
requestURL = getTargetFromProxy(envPath + url)
// #endif
// ****
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14