6V6k0jPFP

23朵毒蘑菇

XMLHttpRequest的简单封装,100多行代码,超轻量。

原文章迁移

js|XMLHttpRequest

2021-08-18 18:33:10 已有版本 1 个 show:0.61kTYPE: blog

直接看代码。可以进行请求拦截,返回数据拦截,并不是用promise进行封装的,因为需要使用到上传进度,所以是简单的回调方式封装的。

/*jshint esversion: 9 */
//回调类型请求工具
//官方文档 https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest
class XMLHttp{
    constructor({
        timeOut=13000000,
        baseUrl='',
    }={}){
        this.timeOut = timeOut;
        this.baseUrl = baseUrl;
        this.intercept = {  //拦截器
            request:{
                success:undefined,
                error:undefined,
            },
            response:{
                success:undefined,
                error:undefined,
            },
        };
    }
    createRequest({
        method,url,params,responseType,async=true,withCredentials=false,
        readyStateChange,
        loadStart,
        progress,
        abort,
        error,
        load,
        timeOut,
        loadend,
    }){
        try{
            const xhr = new XMLHttpRequest();
            xhr.onreadystatechange = ()=>{
                readyStateChange && readyStateChange(xhr);
            };
            xhr.upload.addEventListener("progress", (evt)=>{  //上传进度
                progress && progress(evt);
            });
            xhr.addEventListener("load", ()=>{
                load && load(xhr);
            });
            xhr.addEventListener("error", ()=>{
                error && error(xhr);
            });
            xhr.addEventListener("abort", ()=>{
                abort && abort(xhr);
            });
            xhr.addEventListener("loadstart", ()=>{
                loadStart && loadStart(xhr);
            });
            xhr.addEventListener("loadend", ()=>{
                loadend && loadend(xhr);
            });
            if(async){  //异步才添加超时
                xhr.timeout = this.timeOut;
                xhr.addEventListener("timeout", ()=>{
                    timeOut && timeOut(xhr);
                });
                xhr.responseType = responseType || 'text';  //返回数据类型
            }
            xhr.withCredentials = withCredentials;  //指示是否应使用Cookie或授权标头等凭据进行跨站点访问控制请求。
            xhr.open(
                method ? method.toUpperCase() : 'GET',
                this.baseUrl + url,
                async,
            );
            this.intercept.request.success && this.intercept.request.success(xhr);  //请求拦截
            xhr.send(params);
            return xhr;
        }catch(e){
            this.intercept.request.error && this.intercept.request.error(e);
        }
    }
    setRequestIntercept(success,error){  //写入请求拦截器
        this.intercept.request.success = success;
        this.intercept.request.error = error;
    }
    setResponseIntercept(success,error){  //写入返回数据拦截器
        this.intercept.response.success = success;
        this.intercept.response.error = error;
    }
    requestMode({  //请求方式
        url='',params={},async,withCredentials,method,
        onSuccess=()=>{},
        error=()=>{},
        progress=()=>{},
        loadend=()=>{},
    }={}){
        return this.createRequest({
            url,
            params,
            async,
            withCredentials,
            method,
            progress,
            loadend,
            readyStateChange:(xhr)=>{
                if(xhr.readyState !== 4) return;
                if(xhr.status === 200) {  //请求成功正确
                    this.intercept.response.success?  //返回数据拦截
                        this.intercept.response.success(
                            xhr,
                            {
                                onSuccess,
                                error,
                            },
                        ):
                        onSuccess(xhr);
                } else {  //请求失败
                    this.intercept.response.error?  //返回数据拦截
                        this.intercept.response.error(
                            xhr,
                            {
                                onSuccess,
                                error,
                            },
                        ):
                        error(xhr);
                }
            },
        });
    }
    get(option){
        return this.requestMode({
            ...option,
            method:'get',
        });
    }
    post(option){
        return this.requestMode({
            ...option,
            method:'post',
        });
    }
    put(option){
        return this.requestMode({
            ...option,
            method:'put',
        });
    }
    delete(option){
        return this.requestMode({
            ...option,
            method:'delete',
        });
    }
}
/*
    test 测试
*/
// let a = new XMLHttp();
// a.get({
//     async:false,
//     method:'get',
//     url:'https://www.w3school.com.cn/js/js_try_catch.asp',
//     onSuccess(xhr){
//         console.log(xhr);
//     },
// })
// console.log(1);

官方XMLHttpRequest文档