封装自己的Ajax库

本文介绍了一个基于Promise模式设计的自定义AJAX框架实现,详细解释了如何通过封装GET、POST等HTTP请求方法来简化异步操作。文章覆盖了从初始化配置到请求处理的全过程,包括请求参数的处理、响应数据的解析以及错误处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

框架基本结构

  1. 声明一个立即执行函数,整体逻辑放在立即执行函数中
  2. 设置默认配置项
  3. 设置核心方法(GET,POST)
(function anonymous(window) {
    //默认配置项
    let _default = {
        method: "GET",  // 请求方式
        url: "", // url
        baseURL: "",
        headers: {}, // 请求头信息
        dataType: "JSON", // 返回格式
        data: null,  // POST请求主题传递给服务器的内容
        params: null, // GET请求基于问号传参传递给服务器的内容
        cache: true,
    };
    // 定义函数 基于promise模式管理AJAX请求
    let ajaxPromise = function ajaxPromise() {};
    // GET方法
    ajaxPromise.get = function (url, options) {};
    // POST方法
    ajaxPromise.post = function (url, data, options) {};
    // 暴露默认配置
    ajaxPromise.defaults = _default;
    // 将定义的函数暴露给window
    window.ajaxPromise = ajaxPromise;
})(window);

设计AJAX请求

  1. 基于promise发送AJAX
  2. 创建XMLHttpRequest 发送请求
  3. GETPOST进行分别处理
let ajaxPromise = function ajaxPromise(options) {
    let {
        url,
        baseURL,
        method,
        data,
        params,
        dataType,
        headers,
        cache,
    } = options;
    // 基于promise设计模式管理Ajax请求
    return new Promise((resolve, reject) => {
        // 创建核心对象
        let xhr = new XMLHttpRequest();
        // 发送请求
        xhr.open(method, baseURL + url);
        // 监听请求
        xhr.onreadystatechange = () => {
            if (xhr.readyState === 4) {
                // 如果成功则执行
                if (/^(2|3)\d{2}$/.test(xhr.status)) {
                    // 更加dataType处理返回结果
                    let result = xhr.responseText;
                    dataType = dataType.toUpperCase();
                    // 根据设置类型进行对数据的处理
                    switch (dataType) {
                        case "JSON":
                            result = JSON.parse(result);
                            break;
                        case "XML":
                            result = xhr.responseXML;
                            break;
                    }
                    resolve(result, xhr);
                    return;
                }
                // 失败执行
                reject(xhr.statusText, xhr);
            }
        };
        // 发送请求数据
        xhr.send(data);
    });
};

封装方GET和POST

// GET 
['get', 'delete', 'head', 'options'].forEach(item => {
    ajaxPromise[item] = function anonymous(url, options = {}) {
        options = {
            ..._default,// 默认值或者基于defaults修改的值
            ...options,// 用户调取方法传递的配置项
            url: url,
            method: item.toUpperCase()/
        };
            return ajaxPromise(options);
    };
});

// POST
['post', 'put', 'patch'].forEach(item => {
    ajaxPromise[item] = function anonymous(url, data = {}, options = {}) {
        options = {
            ..._default,
            ...options,
            url: url,
            method: item.toUpperCase(),
            data: data
        };
        return ajaxPromise(options);
    };
});

完整案例代码

(function anonymous(window) {
  // 设置默认的参数配置项
  let _default = {
    method: "GET",
    url: "",
    baseURL: "",
    headers: {},
    dataType: "JSON",
    data: null, // POST系列请求基于请求主体传递给服务器的内容
    params: null, // GET系列请求基于问号传参传递给服务器的内容
    cache: true,
  };

  // 基于PROMISE设计模式管理AJAX请求
  let ajaxPromise = function ajaxPromise(options) {
    // OPTIONS中融合了:默认配置信息、用户基于DEFAULTS修改的信息、用户执行GET/POST方法时候传递的配置信息,越靠后的优先级越高
    let {
      url,
      baseURL,
      method,
      data,
      dataType,
      headers,
      cache,
      params,
    } = options;

    // 把传递的参数进行处理
    if (/^(GET|DELETE|HEAD|OPTIONS)$/i.test(method)) {
      // GET
      if (params) {
        url += `${ajaxPromise.check(url)}${ajaxPromise.formatData(params)}`;
      }
      if (cache === false) {
        url += `${ajaxPromise.check(url)}_=${+new Date()}`;
      }
      data = null; // GET系列请求主体就是什么都不放
    } else {
      // POST
      if (data) {
        data = ajaxPromise.formatData(data);
      }
    }

    // 基于PROMISE发送AJAX
    return new Promise((resolve, reject) => {
      let xhr = new XMLHttpRequest();
      xhr.open(method, `${baseURL}${url}`);
      // 如果HEADERS存在,需要设置请求头
      if (headers !== null && typeof headers === "object") {
        for (let attr in headers) {
          if (headers.hasOwnProperty(attr)) {
            let val = headers[attr];
            if (/[\u4e00-\u9fa5]/.test(val)) {
              // VAL中包含中文:需要进行编码

              val = encodeURIComponent(val);
            }
            xhr.setRequestHeader(attr, val);
          }
        }
      }
      xhr.onreadystatechange = () => {
        if (xhr.readyState === 4) {
          if (/^(2|3)\d{2}$/.test(xhr.status)) {
            let result = xhr.responseText;
            dataType = dataType.toUpperCase();
            dataType === "JSON"
              ? (result = JSON.parse(result))
              : dataType === "XML"
              ? (result = xhr.responseXML)
              : null;
            resolve(result);
            return;
          }
          reject(xhr.statusText);
        }
      };
      xhr.send(data);
    });
  };

  // 把默认配置暴露出去,后期用户在使用的时候可以自己设置一些基础的默认值(发送AJAX请求的时候按照用户配置的信息进行处理)
  ajaxPromise.defaults = _default;

  // 把对象转换为URLENCODED格式的字符串
  ajaxPromise.formatData = function formatData(obj) {
    let str = ``;
    for (let attr in obj) {
      if (obj.hasOwnProperty(attr)) {
        str += `${attr}=${obj[attr]}&`;
      }
    }
    return str.substring(0, str.length - 1);
  };
  ajaxPromise.check = function check(url) {
    return url.indexOf("?") > -1 ? "&" : "?";
  };

  // GET
  ["get", "delete", "head", "options"].forEach((item) => {
    ajaxPromise[item] = function anonymous(url, options = {}) {
      options = {
        ..._default, // 默认值或者基于defaults修改的值
        ...options, // 用户调取方法传递的配置项
        url: url, // 请求的URL地址(第一个参数:默认配置项和传递的配置项中都不会出现URL,只能这样获取)
        method: item.toUpperCase(), // 以后执行肯定是ajaxPromise.head执行,不会设置METHODS这个配置项,需要手动配置
      };
      return ajaxPromise(options);
    };
  });

  // POST
  ["post", "put", "patch"].forEach((item) => {
    ajaxPromise[item] = function anonymous(url, data = {}, options = {}) {
      options = {
        ..._default,
        ...options,
        url: url,
        method: item.toUpperCase(),
        data: data,
      };
      return ajaxPromise(options);
    };
  });

  window.ajaxPromise = ajaxPromise;
})(window);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值