乐趣区

关于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/
退出移动版