ts + axios封装

https.ts文件

/**
 * @author  作者
 * @time    2020-9-27 8:47
 * @title   http请求封装
 * desc 前后端约定接口返回解构规范
 * {
 *    code: '1',
 *    data:" 请求成功",
 *    message: ""
 * }
 */
import { Interceptor } from './interceptor';
import { message, Modal } from 'ant-design-vue';
import qs from 'qs';

export class Http {
    public axios: any;


    constructor() {
        // 获取axios实例
        this.axios = new Interceptor().getInterceptors();
    }

    /**
     * get请求
     * @param {String} url [请求的url地址]
     * @param {object} params [请求时携带的参数, 默认为空]
     * @param {boolean} download [判断是否是下载请求, 默认为否]
     * @param {boolean} loading [判断是否是需要loading, 默认为否]
     * @desc 由于loading不能一成不变全屏加载,很多种情况都是局部loading,所以当loading为true时,会返回整个response,以便自行处理loading。
     */
    public getData(url: string, params: object = {}, download: boolean = false, loading: boolean = false) {

        return new Promise((resolve, reject) => {
            const config: any = { params };

            if (download) {
                config.responseType = 'blob';
            }

            this.axios.get(url, {
                ...config,
            }).then((res: any) => {
                this.resultHandle(res, resolve, loading);
            }).catch((err: { message: any; }) => {
                reject(err.message);
            });
        });

    }


    /**
     * post请求
     * get请求
     * @param {String} url [请求的url地址]
     * @param {object} data [请求时携带的参数, 默认为空]
     * @param {boolean} download [判断是否是下载请求, 默认为否]
     * @param {boolean} loading [判断是否是需要loading, 默认为否]
     * @param {object} headers [自定义头部信息, 默认为空]
     * @param {boolean} formData [formData格式, 默认为否]
     * desc 由于loading不能一成不变全屏加载,很多种情况都是局部loading,所以当loading为true时,会返回整个response,以便自行处理loading。
     */
    public postData(
        url: string,
        data: object,
        download: boolean = false,
        loading: boolean = false,
        formData: boolean = false,
        headers: object = {},
        ) {
        return new Promise((resolve, reject) => {

            const config: any = {};

            let newData: any = data;

            if (download) {
                config.responseType = 'blob';
                config.headers = {'Content-Type': 'text/plain'};
            }

            if (formData) {
                newData = qs.stringify(data);
                config.headers = { 'Content-Type': 'application/x-www-form-urlencoded' };
            }

            this.axios.post(url, data = newData, {
                ...config,
                headers,
            }).then((res: any) => {
                this.resultHandle(res, resolve, loading);
            }).catch((err: { message: any; }) => {
                reject(err.message);
            });
        });

    }


    /**
     * resultHandle 根据响应code
     * @param {any} res [请求返回值]
     * @param {any} resolve [Promise.resolve]
     * @param {boolean} loading [判断是否是需要loading]
     */
    public resultHandle(
        res: any,
        resolve: { (value?: unknown): void; (value?: unknown): void; (arg0: any): void; },
        loading: boolean) {
        console.log('请求结果:', res);
        if (res.code === '1') {
            resolve(res);
        } else {
            this.errorHandle(res);

            // tslint:disable-next-line:no-unused-expression
            loading && resolve(res);
        }
    }


    /**
     * 服务端状态处理,例如中断性异常,退出异常等等(与拦截器http握手状态注意区分,一般都能分清楚吧)
     * 1000000 为session过期响应码
     * @param {any} res [请求返回值]
     */
    public errorHandle(res: any) {
        // 统一谈服务端提示,我们提示统一由服务端提供
        // 状态码判断
        if (res.code === '1000000') {
            Modal.confirm(
              {
                    title: '你已被登出,可以取消继续留在该页面,或者重新登录',
                    okText: '重新登录',
                    cancelText: '取消',
                    onOk() {
                        // 退出登录
                      console.log('已经退出登录');
                  },
                });
        } else {
            message.error(res.msg);
        }
    }

}

Interceptor文件

/**
 * @author  作者
 * @time    2020-9-27 8:47
 * @title   拦截器封装
 */

import axios from 'axios';
import { message } from 'ant-design-vue';

export class Interceptor {


    /**
     * http握手错误
     * @param res  响应回调,根据不同响应进行不同操作
     */
    private static errorHandle(res: any) {
        // 状态码判断
        switch (res.status) {
            case 401:
                break;
            case 403:
                break;
            case 404:
                message.error('请求的资源不存在');
                break;
            default:
                message.error('连接错误');
        }
    }

    public instance: any;

    constructor() {
        // 创建axios实例
        this.instance = axios.create({timeout: 1000 * 12});
        // 初始化拦截器
        this.initInterceptors();
    }

    // 为了让http.ts中获取初始化好的axios实例
    public getInterceptors() {
        return this.instance;
    }


    // 初始化拦截器
    public initInterceptors() {
        // 设置post请求头
        this.instance.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
        // this.instance.defaults.baseURL = '';
        /**
         * 请求拦截器
         * 每次请求前,如果存在token则在请求头中携带token
         */
        this.instance.interceptors.request.use(
            (config: { headers: { Authorization: string; }; }) => {
                // 登录流程控制中,根据本地是否存在token判断用户的登录情况
                // 但是即使token存在,也有可能token是过期的,所以在每次的请求头中携带token
                // 后台根据携带的token判断用户的登录情况,并返回给我们对应的状态码
                    const token = sessionStorage.getItem('ymNavMap_token');
                    if (token) {
                        config.headers.Authorization = token;
                    }
                    return config;
            },
            (error: any) => {
                console.log(error);
            },
        );


        // 响应拦截器
        this.instance.interceptors.response.use(
            // 请求成功
            (res: {
                status: number;
                headers: object;
                data: { token: string; }; }) => {
                if (res.status === 200 || res.status === 304) {
                    return Promise.resolve(res.data);
                } else {
                    Interceptor.errorHandle(res);
                    return Promise.reject(res.data);
                }
            },
            // 请求失败
            (error: { response: any; }) => {
                const {response} = error;
                if (response) {
                    // 请求已发出,但是不在2xx的范围
                    Interceptor.errorHandle(response);
                    return Promise.reject(response.data);
                } else {
                    // 处理断网的情况
                    // eg:请求超时或断网时,更新state的network状态
                    // network状态在app.vue中控制着一个全局的断网提示组件的显示隐藏
                    // 关于断网组件中的刷新重新获取数据,会在断网组件中说明
                    message.error('网络连接异常,请稍后再试!');
                }
            });
    }
}

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夜丶陌颜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值