util-6.http相关(httpUtil)

/**
 * ========================http========================
 */
var httpUtil = {
    /**
     * XMLHttpRequest是一个浏览器接口,使得Javascript可以进行HTTP(S)通信,这就是我们熟悉的AJAX。
     * xhr.readyState:XMLHttpRequest对象的状态,等于4表示数据已经接收完毕。
     * xhr.status:服务器返回的状态码,等于200表示一切正常。
     * xhr.responseText:服务器返回的文本数据
     * xhr.responseXML:服务器返回的XML格式的数据
     * xhr.statusText:服务器返回的状态文本。
     * @returns {boolean}
     * @constructor
     */
    "XMLHttpRequest": function(){
        var xhr = null;
        if(window.XMLHttpRequest){ //非IE浏览器&IE6+
            xhr = new XMLHttpRequest();
        }else if(window.ActiveXObject){  //IE浏览器:IE5&IE6
            xhr = new ActiveXObject("Microsoft.XMLHTTP");
        }else{
            alert("Your browser does not support XMLHTTP.");
            return false;
        }
        var fileurl = "/..."; //资源请求路径(包含js文件内联实现,或者接口路径等)
        xhr.open("GET",fileurl,true);  //第三个参数为async是否为异步,默认为true
        //监听请求完成事件
        xhr.onreadystatechange = function(){
            if(xhr.readyState == 4 ){ //四个状态: 1.uninitialized 未初始化  2.loading 加载中  3.loaded 加载完成  4.complete 完成
                if(xhr.status>=200&&xhr.status<300 || xhr.status==304){ //200<=状态码<300为有效请求,304为缓存中获取
                    var responsetext = xhr.responseText; //服务器返回的文本数据
                }else{
                    alert(xhr.statusText); //服务器返回的状态文本
                }
            }
        };

        var formData = new FormData();
        formData.append('tel', '18217767969');
        formData.append('psw', '111111');
        xhr.send(formData);  //发送请求内容,没内容时,传值为null
    }
}

/**
 * http.js start
 * @type {{request: http.request, addAuthorizationHeader: http.addAuthorizationHeader, post: http.post, postBody: http.postBody, get: http.get, getQueryString: (function(*=): string), ajax: http.ajax, delete: http.delete, getUrlParam: http.getUrlParam, getQueryData: http.getQueryData}}
 */
const http = {
    /**
     * js封装ajax请求
     * >>使用new XMLHttpRequest 创建请求对象,所以不考虑低端IE浏览器(IE6及以下不支持XMLHttpRequest)
     * >>使用es6语法,如果需要在正式环境使用,则可以用babel转换为es5语法 https://babeljs.cn/docs/setup/#installation
     *
     * @param settings 请求参数模仿jQuery ajax
     * 调用该方法,data参数需要和请求头Content-Type对应
     *  Content-Type                        data                                     描述
     *  application/x-www-form-urlencoded   'name=哈哈&age=12'或{name:'哈哈',age:12}  查询字符串,用&分割
     *  application/json                     name=哈哈&age=12'                        json字符串
     *  multipart/form-data                  new FormData()                           FormData对象,当为FormData类型,不要手动设置Content-Type
     *  注意:请求参数如果包含日期类型.是否能请求成功需要后台接口配合
     */
    "ajax": (settings = {}) => {
        // 初始化请求参数
        let _s = Object.assign({
            url: '', // string
            type: 'GET', // string 'GET' 'POST' 'DELETE'
            dataType: 'json', // string 期望的返回数据类型:'json' 'text' 'document' ...
            async: true, //  boolean true:异步请求 false:同步请求 required
            data: null, // any 请求参数,data需要和请求头Content-Type对应
            headers: {}, // object 请求头
            timeout: 1000, // string 超时时间:0表示不设置超时
            beforeSend: (xhr) => {
            },
            success: (result, status, xhr) => {
            },
            error: (xhr, status, error) => {
            },
            complete: (xhr, status) => {
            }
        }, settings);
        // 参数验证
        if (!_s.url || !_s.type || !_s.dataType || !_s.async) {
            alert('参数有误');
            return;
        }
        // 创建XMLHttpRequest请求对象
        let xhr = new XMLHttpRequest();
        // 请求开始回调函数
        xhr.addEventListener('loadstart', e => {
            _s.beforeSend(xhr);
        });
        // 请求成功回调函数
        xhr.addEventListener('load', e => {
            const status = xhr.status;
            if ((status >= 200 && status < 300) || status === 304) {
                let result;
                if (xhr.responseType === 'text') {
                    result = xhr.responseText;
                } else if (xhr.responseType === 'document') {
                    result = xhr.responseXML;
                } else {
                    result = xhr.response;
                }
                // 注意:状态码200表示请求发送/接受成功,不表示业务处理成功
                _s.success(result, status, xhr);
            } else {
                _s.error(xhr, status, e);
            }
        });
        // 请求结束
        xhr.addEventListener('loadend', e => {
            _s.complete(xhr, xhr.status);
        });
        // 请求出错
        xhr.addEventListener('error', e => {
            _s.error(xhr, xhr.status, e);
        });
        // 请求超时
        xhr.addEventListener('timeout', e => {
            _s.error(xhr, 408, e);
        });
        let useUrlParam = false;
        let sType = _s.type.toUpperCase();
        // 如果是"简单"请求,则把data参数组装在url上
        if (sType === 'GET' || sType === 'DELETE') {
            useUrlParam = true;
            _s.url += http.getUrlParam(_s.url, _s.data);
        }
        // 初始化请求
        xhr.open(_s.type, _s.url, _s.async);
        // 设置期望的返回数据类型
        xhr.responseType = _s.dataType;
        // 设置请求头
        for (const key of Object.keys(_s.headers)) {
            xhr.setRequestHeader(key, _s.headers[key]);
        }
        // 设置超时时间
        if (_s.async && _s.timeout) {
            xhr.timeout = _s.timeout;
        }
        // 发送请求.如果是简单请求,请求参数应为null.否则,请求参数类型需要和请求头Content-Type对应
        xhr.send(useUrlParam ? null : http.getQueryData(_s.data));
    },
    // 把参数data转为url查询参数
    "getUrlParam": (url, data) => {
        if (!data) {
            return '';
        }
        let paramsStr = data instanceof Object ? http.getQueryString(data) : data;
        return (url.indexOf('?') !== -1) ? paramsStr : '?' + paramsStr;
    },
    // 获取ajax请求参数
    "getQueryData": (data) => {
        if (!data) {
            return null;
        }
        if (typeof data === 'string') {
            return data;
        }
        if (data instanceof FormData) {
            return data;
        }
        return http.getQueryString(data);
    },
    // 把对象转为查询字符串
    "getQueryString": (data) => {
        let paramsArr = [];
        if (data instanceof Object) {
            Object.keys(data).forEach(key => {
                let val = data[key];
                // todo 参数Date类型需要根据后台api酌情处理
                if (val instanceof Date) {
                    val = dateFormat(val, 'yyyy-MM-dd hh:mm:ss');
                }
                paramsArr.push(encodeURIComponent(key) + '=' + encodeURIComponent(val));
            });
        }
        return paramsArr.join('&');
    },
    /**
     * 根据实际业务情况装饰 ajax 方法
     * 如:统一异常处理,添加http请求头,请求展示loading等
     * @param settings
     */
    "request": (settings = {}) => {
        // 统一异常处理函数
        let errorHandle = (xhr, status) => {
            console.log('request error...');
            if (status === 401) {
                console.log('request 没有权限...');
            }
            if (status === 408) {
                console.log('request timeout');
            }
        };
        // 使用before拦截参数的 beforeSend 回调函数
        settings.beforeSend = (settings.beforeSend || function () {
        }).before(xhr => {
            console.log('request show loading...');
        });
        // 保存参数success回调函数
        let successFn = settings.success;
        // 覆盖参数success回调函数
        settings.success = (result, status, xhr) => {
            // todo 根据后台接口api判断是否请求成功
            if (result && result instanceof Object && result.code !== 1) {
                errorHandle(xhr, status);
            } else {
                console.log('request success');
                successFn && successFn(result, status, xhr);
            }
        };
        // 拦截参数的 error
        settings.error = (settings.error || function () {
        }).before((result, status, xhr) => {
            errorHandle(xhr, status);
        });
        // 拦截参数的 complete
        settings.complete = (settings.complete || function () {
        }).after((xhr, status) => {
            console.log('request hide loading...');
        });
        // 请求添加权限头,然后调用http.ajax方法
        (http.ajax.before(http.addAuthorizationHeader))(settings);
    },
    // 添加权限请求头
    "addAuthorizationHeader": (settings) => {
        settings.headers = settings.headers || {};
        const headerKey = 'Authorization'; // todo 权限头名称
        // 判断是否已经存在权限header
        let hasAuthorization = Object.keys(settings.headers).some(key => {
            return key === headerKey;
        });
        if (!hasAuthorization) {
            settings.headers[headerKey] = 'test'; // todo 从缓存中获取headerKey的值
        }
    },
    "get": (url, data, successCallback, dataType = 'json') => {
        http.request({
            url: url,
            type: 'GET',
            dataType: dataType,
            data: data,
            success: successCallback
        });
    },
    "delete": (url, data, successCallback, dataType = 'json') => {
        http.request({
            url: url,
            type: 'DELETE',
            dataType: dataType,
            data: data,
            success: successCallback
        });
    },
    // 调用此方法,参数data应为查询字符串或普通对象
    "post": (url, data, successCallback, dataType = 'json') => {
        http.request({
            url: url,
            type: 'POST',
            dataType: dataType,
            data: data,
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
            },
            success: successCallback
        });
    },
    // 调用此方法,参数data应为json字符串
    "postBody": (url, data, successCallback, dataType = 'json') => {
        http.request({
            url: url,
            type: 'POST',
            dataType: dataType,
            data: data,
            headers: {
                'Content-Type': 'application/json; charset=UTF-8'
            },
            success: successCallback
        });
    }
};

Function.prototype.before = function (beforeFn) { // eslint-disable-line
    let _self = this;
    return function () {
        beforeFn.apply(this, arguments);
        _self.apply(this, arguments);
    };
};

Function.prototype.after = function (afterFn) { // eslint-disable-line
    let _self = this;
    return function () {
        _self.apply(this, arguments);
        afterFn.apply(this, arguments);
    };
};

// 日期格式化
const dateFormat = (date, sFormat = 'yyyy-MM-dd') => {
    if (!(date instanceof Date)) {
        return;
    }
    let time = {
        Year: 0,
        TYear: '0',
        Month: 0,
        TMonth: '0',
        Day: 0,
        TDay: '0',
        Hour: 0,
        THour: '0',
        hour: 0,
        Thour: '0',
        Minute: 0,
        TMinute: '0',
        Second: 0,
        TSecond: '0',
        Millisecond: 0
    };
    time.Year = date.getFullYear();
    time.TYear = String(time.Year).substr(2);
    time.Month = date.getMonth() + 1;
    time.TMonth = time.Month < 10 ? '0' + time.Month : String(time.Month);
    time.Day = date.getDate();
    time.TDay = time.Day < 10 ? '0' + time.Day : String(time.Day);
    time.Hour = date.getHours();
    time.THour = time.Hour < 10 ? '0' + time.Hour : String(time.Hour);
    time.hour = time.Hour < 13 ? time.Hour : time.Hour - 12;
    time.Thour = time.hour < 10 ? '0' + time.hour : String(time.hour);
    time.Minute = date.getMinutes();
    time.TMinute = time.Minute < 10 ? '0' + time.Minute : String(time.Minute);
    time.Second = date.getSeconds();
    time.TSecond = time.Second < 10 ? '0' + time.Second : String(time.Second);
    time.Millisecond = date.getMilliseconds();

    return sFormat.replace(/yyyy/ig, String(time.Year))
        .replace(/yyy/ig, String(time.Year))
        .replace(/yy/ig, time.TYear)
        .replace(/y/ig, time.TYear)
        .replace(/MM/g, time.TMonth)
        .replace(/M/g, String(time.Month))
        .replace(/dd/ig, time.TDay)
        .replace(/d/ig, String(time.Day))
        .replace(/HH/g, time.THour)
        .replace(/H/g, String(time.Hour))
        .replace(/hh/g, time.Thour)
        .replace(/h/g, String(time.hour))
        .replace(/mm/g, time.TMinute)
        .replace(/m/g, String(time.Minute))
        .replace(/ss/ig, time.TSecond)
        .replace(/s/ig, String(time.Second))
        .replace(/fff/ig, String(time.Millisecond));
};
/**
 * http.js end
 */

/**
 * 调用页面代码 s
 */

/*
<!DOCTYPE html>
<html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>Title</title>
    </head>
    <body>
    <div id="buttons">
    <button id="get">get</button>
    <button id="get_dataParam">get_dataParam</button>
    <button id="get_timeout">get_timeout</button>
    <button id="get_document">get_document</button>
    <button id="get_exception">get_exception</button>
    <button id="post_dataParam">post_dataParam</button>
    <button id="post_formDataParam">post_formDataParam</button>
    <button id="post_body">post_body</button>
    <button id="post_body_list">post_body_list</button>
    </div>
    <br>
    <div>
    <label for="file">选择文件,可多选:</label>
<input id="file" type="file" multiple>
<button id="upload">upload</button>
    </div>
    <br>
    <div>
    <label for="file">文件分块传输:</label>
<input id="bidFile" type="file">
    <button id="uploadFile">uploadFile</button>
    </div>
    <script src="http.js"></script>
    <script>
    document.getElementById('buttons').addEventListener('click', function (e) {
        let url = 'http://88.128.18.144:8081/api/v1/test/';
        const id = e.target.id;
        if (id === 'get') {
            url = url + id;
            fetch(url + '?name=哈哈&age=12').then(res => res.json()).then(data => {
                console.log(data);
            });
        }
        if (id === 'get_dataParam') {
            http.request({
                url: url + id,
                data: {name: '哈哈', age: 12}, //data: 'name=哈哈&age=12',
                success: function (result, status, xhr) {
                    console.log(result, '\n status:', status, xhr);
                    debugger;
                }
            });
        }
        if (id === 'get_timeout') {
            http.request({
                url: url + id,
                timeout: 1000
            });
        }
        if (id === 'get_document') {
            // http.request是针对这个api(http://88.128.18.144:8081/api/)封装的,这里请求另外一个接口,不能使用http.request
            http.ajax({
                url: 'http://172.16.19.136:9000/kit_file_server/',
                dataType: 'document',
                success: function (result, status, xhr) {
                    console.log(result, '\n status:', status, xhr);
                    debugger;
                }
            });
        }
        if (id === 'get_exception') {
            http.get(url + id);
        }
        if (id === 'post_dataParam') {
            url = url + id;
            http.post(url, {name: '哈哈', age: 12}, (result, status, xhr) => {
                console.log('进行业务操作');
            })
        }
        if (id === 'post_formDataParam') {
            // 传FormData类型参数,不要设置contentType,浏览器会自动设置contentType为'multipart/form-data'
            let formData = new FormData();
            formData.append('name', '哈哈');
            formData.append('age', '123');
            http.request({
                url: url + id,
                type: 'POST',
                data: formData,
                success: function (result, status, xhr) {
                    console.log('进行业务操作');
                }
            });
        }
        if (id === 'post_body') {
            url = url + id;
            http.postBody(url, JSON.stringify({
                name: '哈哈',
                age: 12,
                birthday: dateFormat(new Date(), 'yyyy-MM-dd hh:mm:ss'),
                hobbies: ['a', 'b', 'c']
            }), (result, status, xhr) => {
                console.log('进行业务操作');
            });
        }
        if (id === 'post_body_list') {
            url = url + id;
            http.postBody(url, JSON.stringify(['a', 'b', 'c']), (result, status, xhr) => {
                console.log('进行业务操作');
            });
        }
    });
document.getElementById('upload').addEventListener('click', function () {
    let files = document.getElementById('file').files;
    if (files.length === 0) {
        console.log('没有选择文件');
        return;
    }
    let form = new FormData(); // FormData 对象
    Array.from(files).forEach((file, index) => {
        form.append(index, file); // 文件对象
    });
    http.ajax({
        url: 'http://88.128.18.144:3333/upload?directory=test',
        type: 'POST',
        data: form,
        success: function (result, status, xhr) {
            console.log('文件上传成功', result.data);
        }
    });
});
const LENGTH = 1024 * 100; // 100kb
document.getElementById('uploadFile').addEventListener('click', function () {
    let file = document.getElementById('bidFile').files[0];
    if (!file) {
        console.log('没有选择文件');
        return;
    }
    let start = 0, end = LENGTH;
    while (start < file.size) {
        let blob = file.slice(start, end);
        let form = new FormData();
        form.append('blob', blob);
        http.ajax({
            url: 'http://88.128.18.144:3333/upload?directory=test',
            type: 'POST',
            data: form,
            success: function (result, status, xhr) {
                console.log('文件分块上传', result.data);
            }
        });
        start = end;
        end = start + LENGTH;
    }
});
</script>
</body>
</html>
*/
/**
 * 调用页面代码 e
 */

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值