封装ajax

封装ajax

原生js实现ajax封装

封装ajax

function ajax (options) {
  return new Promise((resolve, reject) => {
    var xhr = new XMLHttpRequest();
    var method = (options.method || "GET").toUpperCase();
    var url = options.url;
    var isAsync = options.async !== false;
    var data = options.data || null;
    var timeout = options.timeout || 0;
    var headers = options.headers || {};
    var xhrFields = options.xhrFields || {};
    var beforeSend = options.beforeSend || function () { };
    var onUploadProgress = options.onUploadProgress || function () { };
    var onDownloadProgress = options.onDownloadProgress || function () { };

    // 处理GET请求中的数据作为URL参数
    if (method === "GET" && data) {
      var queryParams = '';
      if (typeof data === 'string') {
        // 假设字符串已经是合适的查询字符串格式
        queryParams = data.startsWith('?') ? data.substring(1) : data;
      } else if (typeof data === 'object') {
        // 将对象转换为查询字符串
        queryParams = new URLSearchParams(data).toString();
      }
      url += (url.includes('?') ? '&' : '?') + queryParams;
    }

    xhr.open(method, url, isAsync);
    beforeSend(xhr);

    // 设置请求头
    if (method === "POST" && !options.contentType && !headers["Content-Type"]) {
      xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
    }
    for (let key in headers) {
      xhr.setRequestHeader(key, headers[key]);
    }

    // 设置额外的XHR属性
    for (let field in xhrFields) {
      xhr[field] = xhrFields[field];
    }

    // 上传进度监控
    xhr.upload.onprogress = function (event) {
      if (event.lengthComputable) {
        onUploadProgress(event);
      }
    };

    // 下载进度监控
    xhr.onprogress = function (event) {
      if (event.lengthComputable) {
        onDownloadProgress(event);
      }
    };

    xhr.onreadystatechange = function () {
      if (xhr.readyState === 4) {
        if (xhr.status >= 200 && xhr.status < 300) {
          resolve(xhr.responseText);
        } else if (xhr.status === 0) {
          reject(new Error("请求未发送或网络连接问题"));
        } else {
          reject(new Error("请求失败: 状态码 " + xhr.status + " " + xhr.statusText));
        }
      }
    };

    // 网络错误处理
    xhr.onerror = function () {
      reject(new Error("网络错误"));
    };

    // 超时处理
    xhr.timeout = timeout;
    xhr.ontimeout = function () {
      reject(new Error("请求超时"));
    };

    xhr.send(method === "POST" || method === "PUT" ? data : null);
  });
}
Comment