封裝axios請求並對提交引數進行校驗

Echi灬丨無痕發表於2019-04-16

本文同步更新於我的github點選前往。主要講解如何攔截axios請求,並對請求引數進行校驗,防止提交非法值。當然,你也可以直接用於表單引數校驗,使用的校驗工具是async-validator檢視詳情;之前曾用它封裝過Vue的form表單元件,這個找個時間再出個教程,教你如何封裝屬於自己的Vue元件。

由於本人一直在用Typescript作開發,所以提交的檔案字尾名是.ts結尾的。你也可以自行修改字尾名,並將裡面的型別宣告去除即可;

檔案說明

root:
 |--validator # 校驗方法
 |--axios # axios封裝請求//攔截配置
 |    |--config.ts # axios攔截器配置檔案
 |    |--service,ts # axios請求配置檔案

複製程式碼

一直以來,我們在提交請求時經常會遇到這樣的情況,就是提交的引數與後臺所需不一致; 這樣一來,無疑就浪費了一次請求。特別的是在網路比較慢的情況下,返回需要的時間過長,這樣對使用者來說體驗很不好。

使用

API 請求

    // api
    import service from 'path/service';
    import {
        validate
    } from 'path/validator';

    // 當個請求引數校驗
    function anyRequest(id) {
        // 
        return service.get({
            url: `path/${id}`
        }, {
            fileds: {
                id: '需要校驗的引數名'
            },
            rules: {
                id: [validate.isRequired],
            }
        });
    }
    
    // 多個請求引數校驗
    function anyRequest(id, obj) {
        // 
        return service.post({
            url: `path/${id}`,
            data: {
                name: 'Echi',
                age: '26'
            }
        }, {
            fileds: {
                id: '需要校驗的引數名',
                obj: '這是一個物件'
            },
            rules: {
                id: [validate.isRequired],
                obj: {
                    ...validate.isObject,
                    fileds: {
                        name: [validate.isRequired],
                        age: [validate.isRequired],
                    }
                }
            }
        });
    }

複製程式碼

校驗方法及引數設定

    // validator
    import AsyncValidator from 'async-validator';

    /**
     * 校驗請求引數規則
     * @desc 用於表單校驗,通過非同步校驗,當校驗出錯時會丟擲異常
     * @export
     * @param [Object] [fileds={key: value}] 需要校驗的欄位
     * @param [Object] [rules={key: validator}]  // 校驗規則
     * @returns void
     */
    export default function requestValidator(fileds = {}, rules = {}) {
        return new Promise((resolve, reject) => {
            const validator = new AsyncValidator(rules);
            validator.validate(fileds, {
                firstFields: true
            }, (errors, data) => {
                const status = !errors ? 'success' : 'error';
                const message = errors ? errors[0].message : '';
                if (status === 'success') {
                    resolve({
                        status,
                        message,
                        data
                    });
                } else {
                    console.warn(`當前引數校驗不通過,錯誤資訊: ${message}`);
                    reject({
                        status,
                        message,
                        data,
                        isValid: true
                    });
                }
            });
        });
    }

    // 校驗規則
    // 欄位擴充套件請看 https://github.com/yiminghe/async-validator
    export const validate = {
        // 必填項
        isRequired: {
            required: true
        },
        // 字串校驗
        isString: {
            type: 'string'
        },
        // 物件校驗
        isObject: {
            type: 'object'
        },
        // 陣列校驗
        isArray: {
            type: 'array'
        },
        // 數值校驗
        isNumber: {
            type: 'number'
        }
    };

複製程式碼

封裝axios請求

    // service
    import axios from './config';
    import requestValidator from '../validator';

    // HTTP工具類
    export default class Http {
    public static async request(params: any, descriptor ?: any) {
        // 新增請求攔截校驗
        if (descriptor !== undefined) {
            let fileds = descriptor.fileds || {};
            let rules = descriptor.rules || {};
            await requestValidator(fileds, rules);
        }
        return await axios(params);
    }

    /**
     * get
     * @param [url] 地址
     * @param [data] 資料
     * @returns Promise
     */
    public static get(req: any, descriptor ?: any): any {
        return this.request({
            method: 'GET',
            url: `/${req.url}`,
            params: req.data,
        }, descriptor);
    }

    /**
     * put
     * @param [url] 地址
     * @param [data] 資料
     * @returns Promise
     */
    public static put(req: any, descriptor ?: any): any {
        return this.request({
            method: 'PUT',
            url: `/${req.url}`,
            data: req.data,
        }, descriptor);
    }

    /**
     * post
     * @param [url] 地址
     * @param [data] 資料
     * @returns Promise
     */
    public static post(req: any, descriptor ?: any): any {
        return this.request({
            method: 'post',
            url: `/${req.url}`,
            data: req.data,
        }, descriptor);
    }

    /**
     * delete
     * @param [url] 地址
     * @param [data] 資料
     * @returns Promise
     */
    public static delete(req: any, descriptor ?: any): any {
        return this.request({
            method: 'DELETE',
            url: `/${req.url}`,
            params: req.data,
            }, descriptor);
        }
    }

複製程式碼

最後,謝謝大家的觀看,如果有什麼疑問或有更好的寫法,歡迎分享~

相關文章