请求上传
duxapp对请求上方法传进行了封装,增加了更丰富的功能,封装实现了下面的特性
- 请求拦截器(中间件)
- 错误提醒
- 加载中
- 防止过快请求
- 请求hook封装
- hook缓存
创建
// 定义一个请求配置,这个配置可以通用于请求和上传
const config = {
config: {
request: {
origin: config.origin, // 从用户配置读取请求域名
path: config.path, // 从用户配置读取请求二级路径
contentType: 'application/json'
},
result: {
code: 'statusCode',
data: ['data', 'data'],
succesCode: 200,
message: res => {
if (res.statusCode === 200) {
return res.data.message
}
return res.data
}
},
upload: {
api: 'member/upload', // 上传文件接口
requestField: 'file',
resultField: ['data', 'data', 0, 'url']
}
},
// 默认使用的中间件(请求拦截)
middle: {
}
}
const { request, throttleRequest, middle: requestMiddle } = createRequest(config)
const { upload, uploadTempFile, middle: uploadMiddle } = createRequest(config)
export {
request,
throttleRequest,
requestMiddle,
upload,
uploadTempFile,
uploadMiddle
}
使用
从上面导出的文件导入请求函数
import { request, upload } from '@/modeName'
// get请求
const res = await request('mall/list')
// post请求
const res = await request({
url: 'mall/list',
method: 'POST'
})
// 上传单个图片
const [url] = await upload('image', { count: 1 })
// 上传多个图片
const urls = await upload('image', { count: 9 })
// 上传视频
const [url] = await upload('video', { count: 1 })
更多请查看请求上传
中间件
通常后端都有一套请求认证流程,通过请求拦截就能很好的处理这些问题,例如duxcms的认证认证签名过程如下
const before = async params => {
const timestamp = Math.round(new Date().getTime() / 1000)
const [orign, query] = params.url.split('?')
const paths = orign.split('/').slice(orign.startsWith('http') ? 3 : 1)
const contentDate = timestamp.toString()
const signData = []
signData.push('/' + paths.join('/'))
signData.push(qs.stringify({
...params.query,
...query ? qs.parse(query) : {}
}, { encode: false }))
// signData.push(contentMD5)
signData.push(contentDate)
const hash = hmacSha256(signData.join('\n'), config.secretKey)
const sign = encHex.stringify(hash)
params.header = {
Accept: 'application/json',
AccessKey: config.secretId,
'Platform': getPlatform(),
'Content-MD5': sign,
'Content-Date': contentDate,
...params.header,
}
return params
}
// 上传和请求共用一个拦截器
requestMiddle.before(before, 10)
uploadMiddle.before(before, 10)
然后对返回的结果进行进一步的处理
requestMiddle.result(async (res) => {
if (res.statusCode === 200) {
const data = res.data.data || {}
data._meta = res.data.meta
return data
}
throw {
...(res.data && typeof res.data === 'object' ? res.data : { data: res.data }),
code: res.statusCode,
message: res.data?.message || res.data
}
}, 10)
信息
拦截器的第二个参数是运行顺序,数字越大的越在后面运行