166 lines · 3.4 KB · JavaScript
RawDownload
const MIME_TYPES = {  json: "application/json",  html: "text/html",}; function ajax(options) {  applyDefaults(options);  serializeData(options);   const xhr = new XMLHttpRequest();  xhr.open(options.type, options.url, options.async);   applyCallbacks(xhr, options);  applyHeaders(xhr, options);   xhr.send(options.data);   if (options.async) {    return { abort: abort.bind(undefined, xhr) };  } else {    return parseResponse(xhr, options);  }   function applyDefaults(options) {    for (var key in ajax.defaults) {      if (options[key] == null) {        options[key] = ajax.defaults[key];      }    }  }   function serializeData(options) {    if (!options.data) {      return;    }     if (options.type === "GET") {      options.url += "?" + serializeParams(options.data);      options.data = null;    } else {      options.data = serializeParams(options.data);    }  }   function serializeParams(params) {    return Object.entries(params)      .map(        ([key, value]) =>          `${encodeURIComponent(key)}=${encodeURIComponent(value)}`,      )      .join("&");  }   function applyCallbacks(xhr, options) {    if (!options.async) {      return;    }     xhr.timer = setTimeout(      onTimeout.bind(undefined, xhr, options),      options.timeout * 1000,    );    if (options.progress) {      xhr.onprogress = options.progress;    }    xhr.onreadystatechange = function () {      if (xhr.readyState === 4) {        clearTimeout(xhr.timer);        onComplete(xhr, options);      }    };  }   function applyHeaders(xhr, options) {    if (!options.headers) {      options.headers = {};    }     if (options.contentType) {      options.headers["Content-Type"] = options.contentType;    }     if (      !options.headers["Content-Type"] &&      options.data &&      options.type !== "GET"    ) {      options.headers["Content-Type"] = "application/x-www-form-urlencoded";    }     if (options.dataType) {      options.headers["Accept"] =        MIME_TYPES[options.dataType] || options.dataType;    }     for (var key in options.headers) {      var value = options.headers[key];      xhr.setRequestHeader(key, value);    }  }   function onComplete(xhr, options) {    if (200 <= xhr.status && xhr.status < 300) {      const response = parseResponse(xhr, options);      if (response != null) {        onSuccess(response, xhr, options);      } else {        onError("invalid", xhr, options);      }    } else {      onError("error", xhr, options);    }  }   function onSuccess(response, xhr, options) {    if (options.success != null) {      options.success.call(options.context, response, xhr, options);    }  }   function onError(type, xhr, options) {    if (options.error != null) {      options.error.call(options.context, type, xhr, options);    }  }   function onTimeout(xhr, options) {    xhr.abort();    onError("timeout", xhr, options);  }   function abort(xhr) {    clearTimeout(xhr.timer);    xhr.onreadystatechange = null;    xhr.abort();  }   function parseResponse(xhr, options) {    if (options.dataType === "json") {      return parseJSON(xhr.responseText);    } else {      return xhr.responseText;    }  }   function parseJSON(json) {    try {      return JSON.parse(json);    } catch (error) {}  }} ajax.defaults = {  async: true,  dataType: "json",  timeout: 30,  type: "GET",  // contentType  // context  // data  // error  // headers  // progress  // success  // url};