vue中二次封装axios请求,支持url参数拼接、blob数据流和formdata上传等

现在vue项目基本上都是使用axios进行请求操作,但是axios有时候并不能完全满足业务的需求,因为官方axios只支持一些比较规则的请求参数和方式,比如body类型的post,params类型的get。

而实际业务中后台给的接口可不会那么如你所愿的规范,当后台同事肆意挥洒,尽情装逼,完全是即兴发挥,不考虑前端感受的时候,往往给出来的api接口是很变态的:

get方法的url后面拼接参数?

没办法,谁让前端是万能的呢,只能将就一下后台同事了。

实际项目中用到的最多的方式就是get和post,所以这里主要以封装get和post为例,patch、delete等方法封装与此类似。

分析:

get请求可以有的组合方式:

1、没有参数

2、有参数,参数以query的形式拼接在url上:api/customer?a=xxx&b=yyy

3、有参数,参数以path的形式拼接到url上:api/customer/xxx/yyy

4、有参数,参数以path的形式替换指定字段拼接到url上:api/customer/xxx/yyy

5、无参数,请求返回的数据为blob数据流形式

6、有参数,请求返回的数据为blob数据流形式,参数以path的形式拼接到url上,api/customer/xxx/yyy

7、有参数,请求返回的数据为blob数据流形式,参数以query的形式拼接到url上,api/customer?a=xxx&b=yyy

post请求可以有的组合方式:

1、没有参数

2、有参数,参数以json格式放在body里

3、有参数,参数以path的形式拼接到url上:api/customer/xxx/yyy

4、有参数,参数以query的形式拼接到url上:api/customer?a=xxx&b=yyy

5、无参数,上传formdata数据,部分参数以以json格式放在body里(选传)

6、有参数,上传formdata数据,部分参数以以json格式放在body里(选传),部分参数以path的形式拼接到url上,api/customer/xxx/yyy

7、有参数,上传formdata数据,部分参数以以json格式放在body里(选传),部分参数以query的形式拼接到url上,api/customer?a=xxx&b=yyy

8、无参数,接收blob数据流,部分参数以以json格式放在body里(选传)

9、无参数,接收blob数据流,部分参数以以json格式放在body里(选传),部分参数以path的形式拼接到url上,api/customer/xxx/yyy

10、无参数,接收blob数据流,部分参数以以json格式放在body里(选传),部分参数以query的形式拼接到url上,api/customer?a=xxx&b=yyy

大致就罗列了这么些可能的组合,太多了!

封装请求:

在文件目录下新建service>reset-api.js和service>api-urls.js

api-urls.js 存放所有api接口

const apis = {
    // get
    get: '/api/shop/customer/get', // get
    getNormal: '/api/shop/customer/query', // query
    getOrderPath: '/api/shop/customer/getOrderPath', // getOrderPath
    getLocationPath: '/api/shop/customer/fileCode/page', // 指定字段替换
    getBlob: '/api/shop/customer/getBlob', // getBlob
    getPathBlob: '/api/shop/customer/getPathBlob', // getPathBlob
    getQueryBlob: '/api/shop/customer/getQueryBlob', // getQueryBlob
    // post
    postBody: '/api/shop/customer/body', // body
    postPath: '/api/shop/customer/body', // bodyPath
    postQuery: '/api/shop/customer/body', // bodyQuery
    postFormData: '/api/shop/customer/formData', // formData
    postFormDataPath: '/api/shop/customer/formDataPath', // formDataAndPath
    postFormDataQuery: '/api/shop/customer/formdataQuery', // formdataAndQuery
    postBlob: '/api/shop/customer/postBlob', // postBlob
    postBlobPath: '/api/shop/customer/postBlobPath', // postBlob
    postBlobQuery: '/api/shop/customer/postBlobQuery', // postBlobQuery
};

export default apis

get封装

为防止ie下get方法读取缓存,在url后默认添加时间戳_t字段

1、没有参数的时候,可直接使用别名方法:

                return axios.get(url, {
                    headers: {
                        token: token,
                    },
                });

 

2、query形式参数,可使用params字段

                return axios.get(url, {
                    params: data,
                    headers: {
                        token: token,
                    },
                });

3、参数按path拼接到url上

                if (Object.keys(data).length) {
                    for (let key in data) {
                        url += `/${data[key]}`;
                    }
                }
                url += `?_t=${Date.now()}`; // 加时间戳,防止ie取缓存
                return axios.get(url, {
                    headers: {
                        token: token,
                    },
                });

4、指定位置替换,path形式拼接到url上

url上必须包含需被替换的字段:api/customer/name/age

传参数时字段必须和要替换的一一对应:{name: 'abc',age:12}

被替换后:api/customer/abc/12

                if (Object.keys(data).length) {
                    for (let key in data) {
                        let reg = new RegExp(key, 'g');
                        url = url.replace(reg, data[key]);
                    }
                }
                url += `?_t=${Date.now()}`; // 加时间戳,防止ie取缓存
                return axios.get(url, {
                    headers: {
                        token: token,
                    },
                });

5、请求blob数据流类型,没有参数

                url += `?_t=${Date.now()}`; // 加时间戳,防止ie取缓存
                return axios({
                    method: 'get',
                    url: url,
                    responseType: 'blob',
                    headers: {
                        token: token,
                    },
                });

6、请求blob数据流类型,参数以path形式拼接

                if (Object.keys(data).length) {
                    for (let key in data) {
                        url += `/${data[key]}`;
                    }
                }
                url += `?_t=${Date.now()}`; // 加时间戳,防止ie取缓存
                return axios({
                    method: 'get',
                    url: url,
                    responseType: 'blob',
                    headers: {
                        token: token,
                    },
                });

7、请求blob数据流类型,参数以query形式拼接

                 if (Object.keys(data).length) {
                    for (let key in data) {
                        url +=
                            url.indexOf('?') < 0
                                ? `?${key}=${data[key]}`
                                : `&${key}=${data[key]}`;
                    }
                }
                url += `?_t=${Date.now()}`; // 加时间戳,防止ie取缓存
                return axios({
                    method: 'get',
                    url: url,
                    responseType: 'blob',
                    headers: {
                        token: token,
                    },
                });

post封装

1、无参数和json格式参数

                return axios.post(url, data, {
                    headers: {
                        token: token,
                    },
                });

3、有参数,部分json格式(可选),部分path拼接

                if (Object.keys(config).length) {
                    for (let key in config) {
                        url += `/${config[key]}`;
                    }
                }
                return axios.post(url, data, {
                    headers: {
                        token: token,
                    },
                });

4、有参数,部分json(可选),部分query拼接

                if (Object.keys(config).length) {
                    for (let key in config) {
                        url +=
                            url.indexOf('?') < 0
                                ? `?${key}=${config[key]}`
                                : `&${key}=${config[key]}`;
                    }
                }
                return axios.post(url, data, {
                    headers: {
                        token: token,
                    },
                });

5、无参数,上传formdata(文件)

                return axios.post(url, formData, {
                    headers: {
                        token: token,
                        'content-type': 'application/x-www-form-urlencoded',
                    },
                });

6、有参数,上传formdata(文件),path拼接

                if (Object.keys(config).length) {
                    for (let key in config) {
                        url += `/${config[key]}`;
                    }
                }
                return axios.post(url, formData, {
                    headers: {
                        token: token,
                        'content-type': 'application/x-www-form-urlencoded',
                    },
                });

7、有参数,上传formdata(文件),query拼接

                if (Object.keys(config).length) {
                    for (let key in config) {
                        url +=
                            url.indexOf('?') < 0
                                ? `?${key}=${config[key]}`
                                : `&${key}=${config[key]}`;
                    }
                }
                return axios.post(url, formData, {
                    headers: {
                        token: token,
                        'content-type': 'application/x-www-form-urlencoded',
                    },
                });

8、接收blob数据流,json格式(可选)

                return axios({
                    method: 'post',
                    url: url,
                    data: data,
                    responseType: 'blob',
                    headers: {
                        token: token,
                    },
                });

9、接收blob数据流,json格式(可选),有path拼接

                if (Object.keys(config).length) {
                    for (let key in config) {
                        url += `/${config[key]}`;
                    }
                }
                return axios({
                    method: 'post',
                    url: url,
                    data: data,
                    responseType: 'blob',
                    headers: {
                        token: token,
                    },
                });

10、接收blob数据流,json格式(可选),有query拼接

                if (Object.keys(config).length) {
                    for (let key in config) {
                        url +=
                            url.indexOf('?') < 0
                                ? `?${key}=${config[key]}`
                                : `&${key}=${config[key]}`;
                    }
                }
                return axios({
                    method: 'post',
                    url: url,
                    data: data,
                    responseType: 'blob',
                    headers: {
                        token: token,
                    },
                });

最后统一整理一下reset-api.js

import Vue from 'vue';
import axios from 'axios';
import config from '@/config';
import apis from '@/service/api-urls';
import { sessionStore } from '@/utils';
const TIMEOUT = 10000; // 接口10秒超时
// console.log(config.envConfig)
const NODE_ENV = (process.env.NODE_ENV || 'development').trim();
const BASE_URL = NODE_ENV === 'development' ? config.envConfig.apiOrigin : '';

axios.defaults.timeout = TIMEOUT;
// 添加请求拦截
axios.interceptors.request.use(
    function(config) {
        // 请求之前处理
        return config;
    },
    function(error) {
        // 请求发生错误处理
        return Promise.reject(error);
    },
);
// 添加响应拦截
axios.interceptors.response.use(
    function(response) {
        return response;
    },
    function(error) {
        return Promise.reject(error);
    },
);

let createAxios = (baseURL, url) => {
    function commonJoinPath(data, url) {
        if (Object.keys(data).length) {
            for (let key in data) {
                url += `/${data[key]}`;
            }
        }
        return url;
    }
    function commonJoinQuery(data, url) {
        for (let key in data) {
            url +=
                url.indexOf('?') < 0
                    ? `?${key}=${data[key]}`
                    : `&${key}=${data[key]}`;
        }
        return url;
    }
    return {
        /*
         * axios get 请求
         * @param {Object} data - 需要的传参,选传,默认值为空对象
         * @param {Object} config - 其他配置项,选传,默认值为空对象
         * */
        get(requestType, data = {}, config = {}) {
            let token = sessionStore.get('userInfo')
                ? sessionStore.get('userInfo').token
                : '12222';
            // console.log(data, baseURL)
            function commonGetPath(url, token) {
                url += `?_t=${Date.now()}`; // 加时间戳,防止ie取缓存
                return axios.get(url, {
                    headers: {
                        token: token,
                    },
                });
            }
            function commonGetBlob(url, token) {
                url += `?_t=${Date.now()}`; // 加时间戳,防止ie取缓存
                return axios({
                    method: 'get',
                    url: url,
                    responseType: 'blob',
                    headers: {
                        token: token,
                    },
                });
            }
            if (requestType === 'normal' || !requestType) {
                // param参数类型
                url += requestType ? '' : `?_t=${Date.now()}`; // 加时间戳,防止ie取缓存
                data = requestType
                    ? Object.assign({}, data, {
                          _t: Date.now(),
                      })
                    : data;
                return axios.get(url, {
                    params: data,
                    headers: {
                        token: token,
                    },
                });
            }
            if (requestType === 'orderPath') {
                // 按顺序拼接到url上
                url = commonJoinPath(data, url);
                return commonGetPath(url, token);
            }
            if (requestType === 'locationPath') {
                //  指定位置拼接到url上
                if (Object.keys(data).length) {
                    for (let key in data) {
                        let reg = new RegExp(key, 'g');
                        url = url.replace(reg, data[key]);
                    }
                }
                // console.log(url)
                return commonGetPath(url, token);
            }
            if (requestType === 'blob') {
                //  返回值为blob数据流
                return commonGetBlob(url, token);
            }
            if (requestType === 'pathBlob') {
                //  返回值为blob数据流
                url = commonJoinPath(data, url);
                return commonGetBlob(url, token);
            }
            if (requestType === 'queryBlob') {
                //  返回值为blob数据流
                url = commonJoinQuery(data, url);
                return commonGetBlob(url, token);
            }
        },
        /*
         * axios post 请求
         * @param {Object} data - 需要的传参,选传,默认值为空对象
         * @param {Object} config - 其他配置项,选传,默认值为空对象
         * */
        post(requestType, data = {}, config = {}) {
            let token = sessionStore.get('userInfo')
                ? sessionStore.get('userInfo').token
                : '2222';
            console.log(requestType);
            function commonPostBody(url, data, token) {
                return axios.post(url, data, {
                    headers: {
                        token: token,
                    },
                });
            }
            function commonPostFormData(url, formData, token) {
                return axios.post(url, formData, {
                    headers: {
                        token: token,
                        'content-type': 'application/x-www-form-urlencoded',
                    },
                });
            }
            function commonPostBlob(url, data, token) {
                return axios({
                    method: 'post',
                    url: url,
                    data: data,
                    responseType: 'blob',
                    headers: {
                        token: token,
                    },
                });
            }
            if (requestType === 'postNormal' || !requestType) {
                return commonPostBody(url, data, token);
            }
            // 除了本身的body为json格式,部分参数以/形式拼接到url上
            if (requestType === 'postPath') {
                url = commonJoinPath(config, url);
                return commonPostBody(url, data, token);
            }
            // 除了本身的body为json格式,部分参数以?a=xx&b=yy形式拼接到url上
            if (requestType === 'postQuery') {
                url = commonJoinQuery(config, url);
                return commonPostBody(url, data, token);
            }
            // 只有formdata参数
            if (requestType === 'formData') {
                return commonPostFormData(url, data, token);
            }
            // 除了formdata参数,部分参数以/形式拼接到url上
            if (requestType === 'postFormDataPath') {
                url = commonJoinPath(config, url);
                return commonPostFormData(url, data, token);
            }
            // 除了formdata参数,部分参数以?a=xx&b=yy形式拼接到url上
            if (requestType === 'postFormDataQuery') {
                url = commonJoinQuery(config, url);
                return commonPostFormData(url, data, token);
            }
            // 返回值为blob
            if (requestType === 'postBlob') {
                console.log(data);
                return commonPostBlob(url, data, token);
            }
            if (requestType === 'postBlobPath') {
                url = commonJoinPath(config, url);
                return commonPostBlob(url, data, token);
            }
            if (requestType === 'postBlobQuery') {
                url = commonJoinQuery(config, url);
                return commonPostBlob(url, data, token);
            }
        },
    };
};

export const api = (key) => {
    return createAxios(BASE_URL, apis[key]);
};

Vue.prototype.$api = api;

调用方式:

        async get() {
            let res = await this.$api('get').get();
        },
        async getQuery() {
            let res = await this.$api('getNormal').get('normal', {
                id: '123',
                name: 'liang',
            });
        },
        async getOrderPath() {
            // 按顺序拼接
            let res = await this.$api('getOrderPath').get('orderPath', {
                fileCode: 'xxxxxxx',
                page: 'x',
            });
        },
        async getLocationPath() {
            // 指定位置拼接
            let res = await this.$api('getLocationPath').get('locationPath', {
                fileCode: '122232323232',
                page: '2',
            });
        },
        async getBlob() {
            // 没有参数
            let resPrams = await this.$api('getBlob').get('blob');
        },
        async getPathBlob() {
            // 有参数
            let resPrams = await this.$api('getPathBlob').get('pathBlob', {
                fileCode: 'xxxxxxx',
                page: 'x',
            });
        },
        async getQueryBlob() {
            // 有参数
            let resPrams = await this.$api('getQueryBlob').get('queryBlob', {
                fileCode: 'xxxxxxx',
                page: 'x',
            });
        },
        // post
        async post() {
            let res = await this.$api('postBody').post();
        },
        async postBody() {
            // body contentType:json
            let res = await this.$api('postBody').post('postNormal', {
                fileCode: 'xxxxxxx',
                page: 'x',
            });
        },
        async postPath() {
            let res = await this.$api('postPath').post(
                'postPath',
                {
                    fileCode: 'xxxxxxx',
                    page: 'x',
                },
                {
                    path1: 222,
                    path2: 333,
                },
            );
        },
        async postQuery() {
            let res = await this.$api('postQuery').post(
                'postQuery',
                {
                    fileCode: 'xxxxxxx',
                    page: 'x',
                },
                {
                    query1: 222,
                    query2: 333,
                },
            );
        },
        // 提交formData
        postFromdata(options) {
            let file = options.file;
            let formData = new FormData();
            formData.append('file', file);
            this.$api('postFormData').post('formData', formData);
        },

        postFromdataPath(options) {
            let file = options.file;
            let formData = new FormData();
            formData.append('file', file);
            this.$api('postFormDataPath').post('postFormDataPath', formData, {
                id: 123,
                name: 'liang',
            });
        },
        postFromdataQuery(options) {
            let file = options.file;
            let formData = new FormData();
            formData.append('file', file);
            this.$api('postFormDataQuery').post('postFormDataQuery', formData, {
                id: 123,
                name: 'liang',
            });
        },
        // 返回值为blob类型
        postBlob() {
            this.$api('postBlob').post('postBlob',{ // data可为空对象
              a:111,
              b:222
            });
        },
        postBlobPath() {
            this.$api('postBlobPath').post( //data可为空对象
                'postBlobPath',
                {
                    fileCode: 'xxxxxxx',
                    page: 'x',
                },
                {
                    path1: 222,
                    path2: 333,
                },
            );
        },
        postBlobQuery() {
            this.$api('postBlobQuery').post( // data可为空对象
                'postBlobQuery',
                {
                    fileCode: 'xxxxxxx',
                    page: 'x',
                },
                {
                    query1: 222,
                    query2: 333,
                },
            );
        },

github地址:https://github.com/LandQ123/lq-components

发布了59 篇原创文章 · 获赞 29 · 访问量 15万+

猜你喜欢

转载自blog.csdn.net/dongguan_123/article/details/103224675