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和defaultFileName3 个自定配置,它们具体的使用规则将在下面的介绍给出。
拦截(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,再判断是登录失效还是请求错误,然后按照对应的方式处理。