0.0.6 • Published 2 years ago

sharegood-cloud-request v0.0.6

Weekly downloads
-
License
MIT
Repository
-
Last release
2 years ago

项目介绍

axios 封装 版本不低于 0.19.2

如何使用

通过 npm 下载安装代码

$ npm install --save sharegood-cloud-request

如果你是 webpack 等环境

import {
    createAxios
} from 'sharegood-cloud-request'

如果你是浏览器环境

<script src="node_modules/sharegood-cloud-request/dist/sharegood-cloud-request.min.js"></script>

<script>
    var Request = window['sharegood-cloud-request']
</script>

http 使用规范

基于 axios 封装的数据请求增强版,主要有如下功能:

  • 支持 Promise
  • 重复请求过滤
  • 支持取消请求
  • 内部封装上传和下载
  • 提供数据请求前以及完成后的多个 Hook 拦截器
  • 支持重试机制
  • 支持防止 CSRF/XSRF

createAxios 的参数

基础参数与 axios 保持一致( axios 相关参数请参阅 http://www.axios-js.com/zh-cn/docs/) | 参数 | 说明 | 类型 | 可选值 | 默认值 | |---------- |-------------- |---------- |-------------------------------- |-------- | | baseURL | 接口前缀| String | — | - | | timeout | 超时时间| Number | — | 15000 | | headers | 请求头| Object | — | - |

个性化参数

参数说明类型可选值默认值
exCancel请求前先取消未完成的请求(通常用于幂等性请求,如列表查询等)Booleanfalse
exRetry失败后是否重试Boolean
exNoHooks跳过所有全局拦截器Boolean
isResponseSuccess判断业务数据是否正确Function-
getResponseSuccess格式化正常的数据Function-
getResponseError格式化错误的数据Function-

http 实例方法 | 参数 | 说明 | 类型 | 可选值 | 默认值 | |---------- |-------------- |---------- |-------------------------------- |-------- | | $uploadFile | 上传文件 http.uploadFile(config)| | — | | | $downloadFile | 下载文件 http.downloadFile(config)| | — | |

基本用法

import {
    createAxios,
    cancel,
    isCancel,
    toFormData,
    qsStringify,
} from 'sharegood-cloud-request'

// get 参数序列化
const params = {
    pageNum: 1,
    pageSize: 10,
    status: [1, 2],
    // ...
}
/**
 * Parameters<qsStringify>[1]['arrayFormat'] 对应的输出
 * repeat(默认)---> pageNum=1&pageSize=10&status=1&status=2
 * brackets --------> pageNum=1&pageSize=10&status[]=1&status[]=2
 * indices ---------> pageNum=1&pageSize=10&status[0]=1&status[1]=2
 */
const paramsSerializer = (params) =>
    qsStringify(params, {
        arrayFormat: repeat
    })
// 返回axios的新实例
export const http = createAxios({
    // axios配置
    headers: {
        'Content-Type': 'application/json;charset=UTF-8',
        //'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
    },
    timeout: 10 * 1000, // 默认超时10s
    baseURL: process.env.VUE_APP_BASEURL_API,
    paramsSerializer,
})

// 调用与axios保存一致  返回结果为response.data 相比axios少一层
http.get('/xxx', config)
http.delete('/xxx', config)
http.post('/xxx', null, config)
http.put('/xxx', null, config)
http.patch('/xxx', null, config)

// 取消请求
http.get('/api/xxxxx', {
    exCancel: '请求的别名'
}).catch((err) => {})
// 如果未完成立即取消
cancel('请求的别名')

// 上传
export const uploadFile = function(config = {}) {
    const data = config.data || {}
    const formData = toFormData(data)
    const url = config.url
    return http.request({
        method: 'post',
        url: url,
        data: formData,
        headers: {
            'content-type': 'multipart/form-data'
        },
        ...config,
    })
}

格式化数据

export const http = createAxios({
    baseURL: process.env.VUE_APP_BASEURL_API,
    /* 
        个性配置 
        payload 为后端返回的json
        比如 {code:0, status: true, successfulPayload:null,unsuccessfulPayload:null,message:'sucess'} 
        */
    isResponseSuccess(payload) {
        if (payload.status) {
            return true
        } else {
            return false
        }
    },
    // 统一将成功结果字段`successfulPayload`改为`data`
    getResponseSuccess(payload) {
        const data = payload.successfulPayload || {}
        return {
            data
        }
    },
    getResponseError(res) {
        let {
            data,
            code,
            message
        } = res
        data = res.unsuccessfulPayload || {}
        return {
            data,
            code,
            message
        }
    },
})

// 下载文件
http.$downloadFile({
    url: '/xxx',
})
// 调用
http.get('/xxx').then(({
    data
}) => {
    console.log(data)
})

// 重试
http.get('/xxx', {
    exRetry: true,
    retry: 3, // 重试次数
    retryDelay: 1000, // 每次重试延时
})
// 请求前先取消未完成的请求(通常用于幂等性请求,如列表查询等)
http.get('/xxx', {
    exCancel: true,
    // 对于 `/xxx/${id}` 这种形式的 path,参考如下:
    // exCancel: '/xxx/*',
    // exCancelName: '/xxx/*',

    // 对于 `/xxx/${id}/yyy` 这种形式的 path,参考如下:
    // exCancel: '/xxx/*/yyy',
    // exCancelName: '/xxx/*/yyy',

    // 严格匹配,参考如下(使用动态名称):
    // exCancel: `/xxx?${params.id}`,
    // exCancelName: `/xxx?${params.id}`,

    // 匹配一类,参考如下(类名不能以斜杠开头):
    // exCancel: 'xxx',
    // exCancelName: 'xxx',

    // 调用时传入,使其具备较高灵活度,以实现不同的应用场景(比如锁定作用范围等):
    // exCancel: opts.cancelName,
    // exCancelName: opts.cancelName,
}).then(({
    data
}) => {
    console.log(data)
})

使用拦截器

在拦截器或相关钩子中 做好数据及状态的传递、异常处理等 ,在业务中不需要有多余的判断或行为,让业务更专注

  • 在业务中,then 不需要进行 res.data.code == 'xxx' 等多余的操作(让拦截器全局处理)
  • 在业务中,catch 不需要处理弹出消息层(让拦截器全局处理)
  • 在业务中,请求过程中不需要处理全局 loading(让相关钩子全局处理)
  • ...
import store from '@/store'
import {
    Message
} from 'element-ui'
// 默认添加请求头
const exAuth = Object.freeze({
    onBefore(config) {
        const {
            token
        } = store.state.user
        config.headers['token'] = token
    },
    onComplete(config, isResolve, resOrErr) {
        // token 失效处理
        if (resOrErr.code === 30203) {
            // 退出登录
        }
    },
})

// 默认出错提示错误 参数 exNoErrorMassage:true 则不提示
const exShowErrMessage = Object.freeze({
    onBefore(config) {},
    // isResolve 业务是否正常 resOrErr 业务数据或者失败数据
    onComplete(config, isResolve, resOrErr) {
        const message = resOrErr.message || ''

        if (message && !config.exNoErrorMassage && !isResolve) {
            Message.error(message)
        }
    },
})
import {
    Loading
} from 'element-ui'
let instance = null // 单例模式
let count = 0
export const exShowLoading = Object.freeze({
    onBefore(config) {
        if (config.exShowLoading) {
            if (!instance || instance.visible === false) {
                instance = Loading.service()
            }
            count++
            config._exShowLoading = true
        }
    },
    onComplete(config) {
        if (config._exShowLoading) {
            if (instance) {
                count--
                if (count <= 0) {
                    instance.close()
                    instance = null
                    count = 0
                }
            }
        }
    },
})

export const http = createAxios({
        baseURL: process.env.VUE_APP_BASEURL_API,
    },
    (instance) => {
        instance.exHooks.add(exAuth)
        instance.exHooks.add(exShowErrMessage)
    },
)

// 调用
http.request({
    url: '/xxx',
    exNoErrorMassage: true, // 响应异常时不要弹出消息层
    exShowLoading: true, // 请求过程中显示全局 loading
}).then(({
    data
}) => {
    console.log(data)
})
0.0.6

2 years ago

0.0.3

3 years ago

0.0.2

3 years ago

0.0.1

3 years ago