关于html:第-40-题如何实现一个-ajax

次要应用以下文件

config.js:ajax 申请配置外围文件

loading.js:element-ui 申请加载动画

index.js:二次封装 config.js 申请并导出该办法,配置申请拦截器、响应拦截器

index.vue:调用 ajax 的示例页面

留神:举荐在 api 目录对立治理所有接口,如果遇到报错请调整正确援用门路

config.js

import loading from './loading.js'; // 加载动画类

const animation = false; // 接口加载动画
const intTimer = 10; // 接口申请超时工夫(秒)

class Config {
    constructor(data) {
        this.method = data.method;
        this.url = data.url;
        this.param = data.param || {};
        this.header = data.header || {};
        this.interceptors = data.interceptors;
        this.response = data.response;

        return this.filter();
    }

    // 创立XHR对象
    createXHR() {
        if (window.XMLHttpRequest) {
            // code for IE7+, Firefox, Chrome, Opera, Safari
            return new XMLHttpRequest();
        } else {
            // code for IE6, IE5
            return new ActiveXObject('Microsoft.XMLHTTP');
        }
    }

    // HTTP申请
    xhrRequest(header, method, url, param, async, interceptors, response) {
        return new Promise(resolve => {
            var xhr = this.createXHR();
            if (animation == true) {
                loading.requestStart(); // 执行动画
            }

            // 申请拦挡
            if (interceptors({ header, method, url: this.url, param: this.param, async })) {
                xhr.open(method, url, async);
                xhr.timeout = 1000 * intTimer; //设置xhr申请的超时工夫
                Object.keys(header).map(key => {
                    xhr.setRequestHeader(key, header[key]);
                });
                xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; application/json; charset=utf-8');
                xhr.send(param);
                xhr.onreadystatechange = () => {
                    if (xhr.readyState == 4 && xhr.status == 200) {
                        loading.requestEnd(); // 完结动画
                        try {
                            let data = JSON.parse(xhr.responseText);

                            resolve(response(data, { header, method, url: this.url, param: this.param, async }));
                        } catch (error) {
                            console.log('接口返回没有任何信息!');
                            resolve(false);
                        }
                    } else {
                        return 'request is unsucessful ' + xhr.status;
                    }
                };
            } else {
                console.error('request interceptor', '申请未收回, 申请拦截器已失效!');
            }

            // 申请超时办法
            xhr.ontimeout = function(e) {
                console.log('接口申请超时!');
                loading.requestEnd(); // 完结动画
            };

            // 申请错误方法
            xhr.onerror = function(e) {
                console.log('接口申请失败');
                loading.requestEnd(); // 完结动画
            };
        });
    }

    // 参数转换
    convParams(param) {
        let mark = '?';
        let hasMark = this.url.indexOf(mark) > 0; // 是否蕴含特殊字符
        if (hasMark) {
            mark = '&';
        }

        let newParams = '';
        let i = 0;
        for (let key in param) {
            if (i > 0) {
                newParams += `&${key}=${param[key]}`;
            } else {
                newParams += `${mark}${key}=${param[key]}`;
            }
            i++;
        }
        return newParams;
    }

    // 数据GET、POST申请解决
    filter() {
        let obj = {
            header: this.header,
            method: this.method,
            url: this.url,
            param: {},
            async: true,
            interceptors: this.interceptors,
            response: this.response
        };

        // 接口名称拼接地位:(1、url) (2、param)

        let newParams = this.convParams(this.param);
        if (this.method == 'GET') {
            obj.url += newParams;
        } else {
            newParams = newParams.replace('?', '');
            obj.param = newParams;
        }

        return this.xhrRequest(obj.header, obj.method, obj.url, obj.param, obj.async, obj.interceptors, obj.response);
    }
}

export default Config;

loading.js

import { Loading } from 'element-ui';

class animation {
    constructor() {
        this.needLoadingRequestCount = 0;
        this.loading
    }

    /**
     * 动画开始
     */
    requestStart() {
        if (this.needLoadingRequestCount === 0) {
            this.loading = Loading.service({
                lock: true,
                text: 'loading...',
                background: 'rgba(0, 0, 0, 0.7)'
            });
        }
        this.needLoadingRequestCount++;
    }

    /**
     * 动画完结
     */
    requestEnd() {
        if (this.needLoadingRequestCount <= 0) return;
        this.needLoadingRequestCount--;
        if (this.needLoadingRequestCount === 0) {
            this.loading.close();
        }
    }
}


export default new animation()

index.js

import Config from './config.js';

/**
 * 接口申请办法
 * @func request
 * @param {Object} method 申请形式: 仅反对GET、POST
 * @param {String} url 申请地址
 * @param {Object} param 申请参数
 */
let request = option => {
    // 配置默认申请参数

    return new Config({
        header: {
            Authorization: 'APPCODE edc39cc1dc5f4c139498322115b99e51'
        },
        method: option.method,
        url: option.url,
        param: option.param,
        interceptors: interceptors,
        response: response
    });
};

/**
 * 申请拦截器
 * @func interceptors
 */
let interceptors = config => {
    return true;
};

/**
 * 响应拦截器
 * @func response
 */
let response = (data, config) => {
    let res;

    // 解决返回格局
    if (data.res) {
        res = data.res;
    } else if (data.data) {
        res = data.data;
    } else {
        res = data;
    }
    return res;
};

export default request;

index.vue

<script>
import request from './index.js';

export default {
    mounted() {
        new request({
            method: 'GET', // 申请形式: GET、POST
            url: 'http://10.10.10.10/xxx/xxx', // 申请地址
            param: {} // 申请参数
        }).then(res => {
            console.log('res', res);
        });
    }
};
</script>

文章的内容/灵感都从下方内容中借鉴

  • 【继续保护/更新 500+前端面试题/笔记】https://github.com/noxussj/In…
  • 【大数据可视化图表插件】https://www.npmjs.com/package…
  • 【利用 THREE.JS 实现 3D 城市建模(珠海市)】https://3d.noxussj.top/

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理