ipmp-request v1.2.3
iPMP request
ipmp-request 是基于Axios的二次封装,使之更符合我们系统的功能需求。
安装
npm install -S ipmp-request
使用
import { axiosRequest, axiosDownload } from 'ipmp-request'
const baseURL = 'http://xxxx'
// 普通请求
export function getUserAccount(params = {}) {
return axiosRequest({
baseURL,
url: '/url1',
method: 'GET',
params,
})
}
// 文件流导出请求
export function exportFile(data = {}) {
return axiosDownload({
baseURL,
url: '/url2',
method: 'POST',
data,
})
}
请求配置(Request Config)
我们规定使用axios(config)
的形式传递请求配置,这样可以保持风格统一,并且方便添加/修改不同请求配置。
export function getUserAccount(params = {}) {
return axiosRequest({
baseURL,
url: '/url3',
method: 'POST',
params, // 当我们遇到POST请求需要用`url`传参时,只需要将`data`改为`params`,而不需要将参数进行序列化.
timeout: 60000, // timeout将覆盖默认配置
onUploadProgress: function (progressEvent) {
// 增加新的请求配置
// Do whatever you want with the native progress event
},
})
}
默认配置
axiosRequest
{
timeout: 30000,
withCredentials: true,
validateStatus(status) {
return status >= 200 && status < 600
},
}
axiosDownload
{
timeout: 60000,
responseType: 'blob',
withCredentials: true,
validateStatus(status) {
return status >= 200 && status < 600
},
}
自定义配置
Axios
支持传入自定义配置(但要注意避开0.19.0
版本,这个版本去掉了自定义配置功能,又在后面的版本中加回),以便在后面的执行过程配合进行各种处理。
我们设置了path
、additionSuccessCodeList
和defaultFileName
3 个自定配置,它们具体的使用规则将在下面的介绍给出。
拦截(Interceptors)
1. 请求拦截(interceptors.request)
普通请求或下载,在请求拦截只做了对自定义配置
path
的处理,后续会根据需求再添加别的处理。新增
keycloak
的请求requestForKeycloak
和下载downloadForKeycloak
:
- 在请求拦截中对自定义配置
path
的处理 - 增加对
headers
设置 token,realm,targetAppId 参数(从 localstorage 中取值设置),任意参数丢失都会跳转 keycloak 登录页(如果 window 全局参数中没有 keycloak 实例,则会抛出错误)。
path 配置处理
有时我们或许会遇到一些不太规范的接口传参定义。如:/user/userName/Fred/password/123456
,其中Fred
是userName
,123456
是password
。
那么只需像如下这种方式对url
稍作修改,再将参数用自定义配置path
传入,即可处理为我们需要的内容。
- 提示:
url
支持用冒号(原本支持,/:\w+/
)和括号(新加支持,/\{\w+\}/
)两种形式来表示参数替换位置,两种形式支持混用(如下示例),但不建议混用。
export function getUserAccount(path = { userName: 'Fred', password: '123456' }) {
return axiosRequest({
baseURL,
url: '/user/userName/:userName/password/{password}',
method: 'GET',
path,
})
}
2. 响应拦截(interceptors.response)
2.1 成功处理
axiosRequest
在普通请求中,我们系统目前规定的成功业务状态码是code='0000'
;又因为历史原因code='0'
也代表成功,所以我们默认的成功业务状态码就有0000
和0
。
但除此之外,也可能会出现有分支的情况。即业务状态码0000
代表执行 A 操作,业务状态码0001
代表执行 B 操作,等等。
所以,我们设置了additionSuccessCodeList
自定义配置,在additionSuccessCodeList
里设置的业务状态码也一样视为成功。
成功后我们将只会返回响应体
export function getUserAccount(params = {}) {
return axiosRequest({
baseURL,
url: '/url4',
method: 'GET',
params,
additionSuccessCodeList: ['0001', '0002'],
})
}
handlerUserAccount() {
getUserAccount.then(res => {
const { data = {} } = res
const { code = '' } = data
if (code === '0000') {
// 执行A
} else if (code === '0001') {
// 执行B
} else {
// 执行C (这里code应该等于'0002')
}
})
}
axiosDownload
在文件流导出请求中,判断响应体为文件流后则视为成功,会从响应头中的filename
字段获取文件名。
如果filename
没有设置文件名,我们设置了defaultFileName
自定义配置字段,可以提供一个默认文件名。
然后使用file-saver
库提供的 API:saveAs
,把文件流生成文件。
注意:
推荐静态文件下载也使用axiosDownload
,这样不仅能统一下载方式,也能解决静态文件跨域、图片/pdf 文件成在浏览器打开但不下载等问题
exportStaticFile() {
const params = {
url: 'http://xxx1/xxxx',
defaultFileName: '静态文件01'
}
axiosDownload(params)
}
2.2 登录失效处理
对普通请求和下载,我们系统登录失效状态的业务码状态码有
code=0401
、code=0004
和sub_code=air.invalid-login
。 当判断到登录失效后,会再判断当前页面所处框架(微前端/老框架 iframe/老框架非 iframe),及baseURL
判断所处环境,确定跳转不同登录页面。新增
keycloak
的请求requestForKeycloak
和下载downloadForKeycloak
,http 状态码401
代表登录失效。 当判断到登录失效后会跳转 keycloak 登录页登录(如果 window 全局参数中没有 keycloak 实例,则会将响应体作为错误抛出)
2.3 无权限处理
请求requestForKeycloak
和下载downloadForKeycloak
,http 状态码 403
代表无权限。当判断到无权限后会跳转我们系统的 403 页面地址。
2.4 错误处理
正常情况有http
状态码,响应体就会有业务状态码,所以我们设置http
状态码 200 到 600 以下的 http
状态码都进入响应拦截中。在排除了登录失效和成功后,进入错误处理。
validateStatus(status) {
return status >= 200 && status < 600
}
- 不同历史版本接口返回的响应体数据结构会有不同
- 如果响应体没有业务状态码,就取
http
状态码对应的错误信息
以上情况会造成错误内容混乱,因此在错误处理中,会将这些内容处理为统一的格式,再抛出。
剩余不在 200 到 600 之间的错误(如请求超时),被响应拦截的 error 捕获,再找到对应的错误信息,进行转化抛出。
async handlerUserAccount() {
try {
const res = await getUserAccount()
// Do whatever you want
} catch (err) {
console.log(err) // -> {code: xxx, message: xxx, data: xxx}
this.$message.error(err) // -> err.message
}
}
axiosDownload
文件流导出请求中响应体为非文件流的情况被判定为失败。这时会先将响应体转成 json,再判断是登录失效还是请求错误,然后按照对应的方式处理。