ajax.js 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. // TODO: This file was created by bulk-decaffeinate.
  2. // Sanity-check the conversion and remove this comment.
  3. /*
  4. * decaffeinate suggestions:
  5. * DS102: Remove unnecessary code created because of implicit returns
  6. * DS205: Consider reworking code to avoid use of IIFEs
  7. * DS207: Consider shorter variations of null checks
  8. * DS208: Avoid top-level this
  9. * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md
  10. */
  11. const MIME_TYPES = {
  12. json: "application/json",
  13. html: "text/html",
  14. };
  15. this.ajax = function (options) {
  16. applyDefaults(options);
  17. serializeData(options);
  18. const xhr = new XMLHttpRequest();
  19. xhr.open(options.type, options.url, options.async);
  20. applyCallbacks(xhr, options);
  21. applyHeaders(xhr, options);
  22. xhr.send(options.data);
  23. if (options.async) {
  24. return { abort: abort.bind(undefined, xhr) };
  25. } else {
  26. return parseResponse(xhr, options);
  27. }
  28. };
  29. ajax.defaults = {
  30. async: true,
  31. dataType: "json",
  32. timeout: 30,
  33. type: "GET",
  34. };
  35. // contentType
  36. // context
  37. // data
  38. // error
  39. // headers
  40. // progress
  41. // success
  42. // url
  43. var applyDefaults = function (options) {
  44. for (var key in ajax.defaults) {
  45. if (options[key] == null) {
  46. options[key] = ajax.defaults[key];
  47. }
  48. }
  49. };
  50. var serializeData = function (options) {
  51. if (!options.data) {
  52. return;
  53. }
  54. if (options.type === "GET") {
  55. options.url += "?" + serializeParams(options.data);
  56. options.data = null;
  57. } else {
  58. options.data = serializeParams(options.data);
  59. }
  60. };
  61. var serializeParams = (params) =>
  62. (() => {
  63. const result = [];
  64. for (var key in params) {
  65. var value = params[key];
  66. result.push(`${encodeURIComponent(key)}=${encodeURIComponent(value)}`);
  67. }
  68. return result;
  69. })().join("&");
  70. var applyCallbacks = function (xhr, options) {
  71. if (!options.async) {
  72. return;
  73. }
  74. xhr.timer = setTimeout(
  75. onTimeout.bind(undefined, xhr, options),
  76. options.timeout * 1000,
  77. );
  78. if (options.progress) {
  79. xhr.onprogress = options.progress;
  80. }
  81. xhr.onreadystatechange = function () {
  82. if (xhr.readyState === 4) {
  83. clearTimeout(xhr.timer);
  84. onComplete(xhr, options);
  85. }
  86. };
  87. };
  88. var applyHeaders = function (xhr, options) {
  89. if (!options.headers) {
  90. options.headers = {};
  91. }
  92. if (options.contentType) {
  93. options.headers["Content-Type"] = options.contentType;
  94. }
  95. if (
  96. !options.headers["Content-Type"] &&
  97. options.data &&
  98. options.type !== "GET"
  99. ) {
  100. options.headers["Content-Type"] = "application/x-www-form-urlencoded";
  101. }
  102. if (options.dataType) {
  103. options.headers["Accept"] =
  104. MIME_TYPES[options.dataType] || options.dataType;
  105. }
  106. for (var key in options.headers) {
  107. var value = options.headers[key];
  108. xhr.setRequestHeader(key, value);
  109. }
  110. };
  111. var onComplete = function (xhr, options) {
  112. if (200 <= xhr.status && xhr.status < 300) {
  113. let response;
  114. if ((response = parseResponse(xhr, options)) != null) {
  115. onSuccess(response, xhr, options);
  116. } else {
  117. onError("invalid", xhr, options);
  118. }
  119. } else {
  120. onError("error", xhr, options);
  121. }
  122. };
  123. var onSuccess = function (response, xhr, options) {
  124. if (options.success != null) {
  125. options.success.call(options.context, response, xhr, options);
  126. }
  127. };
  128. var onError = function (type, xhr, options) {
  129. if (options.error != null) {
  130. options.error.call(options.context, type, xhr, options);
  131. }
  132. };
  133. var onTimeout = function (xhr, options) {
  134. xhr.abort();
  135. onError("timeout", xhr, options);
  136. };
  137. var abort = function (xhr) {
  138. clearTimeout(xhr.timer);
  139. xhr.onreadystatechange = null;
  140. xhr.abort();
  141. };
  142. var parseResponse = function (xhr, options) {
  143. if (options.dataType === "json") {
  144. return parseJSON(xhr.responseText);
  145. } else {
  146. return xhr.responseText;
  147. }
  148. };
  149. var parseJSON = function (json) {
  150. try {
  151. return JSON.parse(json);
  152. } catch (error) {}
  153. };