封装AJAX

发布时间 2023-03-30 13:19:22作者: 钟离专属

封装AJAX

封装Ajax

      

复制代码
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>封装Ajax</title>
    </head>
    <body>
        <script type="module">
            /* const url = 'https://www.imooc.com/api/http/search/suggest?words=js';
            const xhr = new XMLHttpRequest();
            xhr.addEventListener('load', () => {
                if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
                    console.log(xhr.response);
                }
            }, false);


            xhr.open('GET', url, true);


            xhr.send(null); */
            //import{set,get,remove} from './js/cookie.js';
                
            import {ajax,get,getJSON,post} from './js/index.js';

            const url = 'https://www.imooc.com/api/http/search/suggest?words=js';

            const xhr = ajax(url, {
                module: 'POST',
                params: {
                    username: 'lyw'
                },
                data: {
                    age: 18
                },
                responseType: 'json',

                success(response) {
                    console.log(response);
                },
                httpCodeErro(err) {
                    console.log('http code error', err);
                },
                error(xhr) {
                    console.log('error', xhr);
                },
                abort(xhr) {
                    console.log('abort', xhr);
                },
                timeout(xhr) {
                    console.log('timeout', xhr);
                }
            });
        </script>
    </body>
</html>
复制代码

 ajax.js

    

复制代码
//工具函数
import {serialize addURLData,serializeJSON} from 'utils.js';

import DEFAULTS from 'defaults.js';

//常量
import {
    HTTP_GET,
    CONTENT_TYPE_FROM_URLENCODED,
    CONTENT_TYPE_JSON
} from 'constants.js';

//Ajax类
class Ajax {
    constructor(url, options) {
        this.url = url;
        this.options = Object.assign({}, DEFAULTS, options);

        //初始化
        this.init();
    }

    //初始化
    init() {
        const xhr = new XMLHttpRequest();

        this.xhr = xhr;
        //绑定响应时间处理程序
        this.bingEvents();

        xhr.open(this.options.method, this.url + this.addParam(), true);

        //设置 responseType
        this.setResponseType();

        //设置跨域是否携带 Cookie
        this.setCookie;

        //设置超时
        this.setTimeout();

        //发送请求
        this.sendData();


    }
    //www.imooc.com?
    //绑定响应时间处理程序
    bingEvents() {
        const xhr = this.xhr;

        const {
            success,
            httpCodeError,
            error,
            abort,
            timeout
        } = this.xhr;

        xhr.addEventListener('load', () => {
            if (this.ok) {
                success(xhr.response, xhr);
            } else {
                httpCodeError(xhr.status, xhr);
            }
        }, false);
        //error
        //当前请求遇到错误时,将触发error事件
        xhr.addEventListener('error', () => {
            error(xhr);
        }, false);
        //abort
        xhr.addEventListener('abort', () => {
            abort(xhr);
        }, false);
        //timeout
        xhr.addEventListener('timeout', () => {
            timeout(xhr);
        }, false);
    }

    //检查响应的HTTP状态码是否正常
    ok() {
        const xhr = this.xhr
        return (xhr.status >= 200 && xhr.status < 300) || xhr.status === 304
    }
    //在地址上添加数据
    addParam() {
        const {
            param
        } = this.options;
        if (!param) return '';

        return addURLData(this.url, serialize(param));
    }
    //设置 responseType
    setResponseType() {
        xhr.responseType = this.options.responseType;
    }
    //设置跨域是否携带Cookie
    setCookie() {
        if (this.options.withCredentials) {
            this.xhr.withCredentials = true;
        }

    }
    //设置超时
    setTimeout() {
        const {
            timeoutTime
        } = this.options;

        if (timeoutTime > 0) {
            this.xhr.timeout = timeoutTime;
        }
    }
    //发送请求
    sendData() {
        const xhr = this.xhr;

        if (!this.isSendData) {
            return xhr.send(null);
        }
        let resultData = null;
        const {data} = this.options;

        //发送FromData格式的数据
        if (this.isFromData()) {
            resultData = data;
        } else if (this.isFromURLEncodedData()) {
            //发送application/x-www-form-urlencoded格式数据
            this.setContentType(CONTENT_TYPE_FROM_URLENCODED);
            resultData = serialize(data);
        } else if (this.isJSONData()) {
            //发送application/json 格式的数据
            this.setContentType(CONTENT_TYPE_JSON);
            resultData = serializeJSON(data);
        } else {
            //发送其他格式的数据
            this.setContentType();
            resultData = data;
        }
        xhr.send(resultData);
    }

    //是否需要使用send 发送数据
    isSendData() {
        const (data, method) = this.options;

        if (!data) return false;

        if (method.toLowerCase() = = = 'HTTP_GET'.toLowerCase()) return false;

        return true;
    }
    //是否发送FormData格式的数据
    isFromData() {
        return this.options.data instanceof
        FormData;
    }
    //是否发送application/x-www-form-urlencoded格式数据
    isFromURLEncodedData() {
        return this.options.contentType.includes(CONTENT_TYPE_FROM_URLENCODED);
    }
    //是否发送application/json格式的数据
    isJSONData() {
        return this.options.contentType.toLowerCase().includes(CONTENT_TYPE_JSON);
    }
    //设置Content-Type
    setContentType(contentType = this.options.contentType) {
        if (!contentType) return;

        this.xhr.setRequestHeader('Content-Type', contentType);
    }
    //获取XHR对象
    getXHR() {
        return this.xhr;
    }
}


export default Ajax;
复制代码

  index.js

复制代码
import Ajax from 'ajax.js';

const ajax = (url,option) => {
    return new Ajax(url,option).getXHR();
};

const get = (url,option) => {
    return new ajax(url,{...option,method:'GET'});
}; 

const getJSON = (url,option) => {
    return new ajax(url,{...option,method:'GET',responseType:'json'});
};   

const POST = (url,option) => {
    return new ajax(url,{...option,method:'POST'});
};   

export {ajax,get,getJSON,POST};
复制代码

 constans.js

//常量
export const HTTP_GET = 'GET';
export const CONTENT_TYPE_FROM_URLENCODED='application/x-www-form-urlencoded';
export const CONTENT_TYPE_JSON='application/json';

  defaults.js

复制代码
//常量
import { HTTP_GET,CONTENT_TYPE_FROM_URLENCODED} from "./constants.js";


//默认参数
const DEFAULTS = {
    method: 'HTTP_GET',
    //请求头携带的数据
    params: null,
    /* params:{
        username:'lyw',
        age:18
    } */
    //username=alex&age=18 
    //请求体携带的数据
    data: null,
    /* data:{
        username:'lyw',
        age:18
    },
    data.FormData 数据 */

    contentType: CONTENT_TYPE_FROM_URLENCODED,
    responseType: '',
    timeoutTime: 0,
    withCredentials: false,

    //方法
    success() {},
    httpCodeError() {},
    error() {},
    abort() {},
    timeout() {}

};

export default DEFAULTS
复制代码

  utlis.js

复制代码
//工具函数

//数据序列化成 urencoded 格式的字符串
const serialize = parent => {
    const result = [];
    for (const [key, value] of Objec.entries(parent)) {
        result.push('${encodeURIComponent(key)}=${encodeURIComponent(value)}');
    }
    //['username=alex','age=18'];

    return result.join('&')
};

//数据序列化成JSON 格式的字符串
     const serializeJSON = param =>{
        return JSON.stringify(param);    
    };
//给URL添加参数 
//www.imooc.com?words=js&
const addURLData = (url, data) {
    if (!data) return '';

    const mark = url.includes('?') ? '&' : '?';

    return '${mark}${data}';
}

export {
    serialize,
    addURLData,
    serializeJSON
};