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

本文详细介绍了在Vue项目中如何封装axios,处理包括get、post在内的多种请求方式,应对后台不规范接口,如参数拼接、blob数据流等复杂场景。

可以滑到页面最底部,之前的部分为思路部分

现在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,
                },
            );
        },

说明:

1。转载地址:https://blog.csdn.net/dongguan_123/article/details/103224675

2.他这个博客可以优化一下(思路:通过正则替换的方式)

提示:2.1 把动态url的部分替换掉,head为url需正则替换掉的部分,body为query部分;

2.2 get一般比较特殊,传入res.data,其他需传入res(这里含有state,可以通过状态做后续操作)

axios.requestFunc = (type,paramData,callback,errCallback) = >{
	paramData = paramData ? paramData : {}
	let requestData = RequesUrls[type]
	let url = requestData.url
	let method = requestData.method
	let postData = paramData['body'] ? paramData['body'] : {}
	
	// 动态url需要拼接出来
	let urlData = paramData['head'] ? paramData['head'] : {}
	if(urlData&&Object.keys(urlData).length){
		for(let key in urlData){
			let reg = new RegExp(key,'g')
			url = url.replace(reg,urlData[key])
		}
	}
	
	if(method === 'POST'){
		axios.post(url,postData).then(res=>{
			callback(res)
		}).catch(err=>{
			errCallback&&errCallback(err)
		})
	}else if(method === 'PUT'){
		axios.put(url,postData).then(res=>{
			callback(res)
		}).catch(err=>{
			errCallback&&errCallback(err)
		})
	}else if(method === 'DELETE'){
		axios.delete(url,postData).then(res=>{
			callback(res)
		}).catch(err=>{
			errCallback&&errCallback(err)
		})
	}else{
		axios.get(url,postData).then(res=>{
			callback(res.data)
		}).catch(err=>{
			errCallback&&errCallback(err)
		})
	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值