request.js 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.default = upload;
  6. function getError(option, xhr) {
  7. var msg = "cannot ".concat(option.method, " ").concat(option.action, " ").concat(xhr.status, "'");
  8. var err = new Error(msg);
  9. err.status = xhr.status;
  10. err.method = option.method;
  11. err.url = option.action;
  12. return err;
  13. }
  14. function getBody(xhr) {
  15. var text = xhr.responseText || xhr.response;
  16. if (!text) {
  17. return text;
  18. }
  19. try {
  20. return JSON.parse(text);
  21. } catch (e) {
  22. return text;
  23. }
  24. }
  25. function upload(option) {
  26. // eslint-disable-next-line no-undef
  27. var xhr = new XMLHttpRequest();
  28. if (option.onProgress && xhr.upload) {
  29. xhr.upload.onprogress = function progress(e) {
  30. if (e.total > 0) {
  31. e.percent = e.loaded / e.total * 100;
  32. }
  33. option.onProgress(e);
  34. };
  35. }
  36. // eslint-disable-next-line no-undef
  37. var formData = new FormData();
  38. if (option.data) {
  39. Object.keys(option.data).forEach(function (key) {
  40. var value = option.data[key];
  41. // support key-value array data
  42. if (Array.isArray(value)) {
  43. value.forEach(function (item) {
  44. // { list: [ 11, 22 ] }
  45. // formData.append('list[]', 11);
  46. formData.append("".concat(key, "[]"), item);
  47. });
  48. return;
  49. }
  50. formData.append(key, value);
  51. });
  52. }
  53. // eslint-disable-next-line no-undef
  54. if (option.file instanceof Blob) {
  55. formData.append(option.filename, option.file, option.file.name);
  56. } else {
  57. formData.append(option.filename, option.file);
  58. }
  59. xhr.onerror = function error(e) {
  60. option.onError(e);
  61. };
  62. xhr.onload = function onload() {
  63. // allow success when 2xx status
  64. // see https://github.com/react-component/upload/issues/34
  65. if (xhr.status < 200 || xhr.status >= 300) {
  66. return option.onError(getError(option, xhr), getBody(xhr));
  67. }
  68. return option.onSuccess(getBody(xhr), xhr);
  69. };
  70. xhr.open(option.method, option.action, true);
  71. // Has to be after `.open()`. See https://github.com/enyo/dropzone/issues/179
  72. if (option.withCredentials && 'withCredentials' in xhr) {
  73. xhr.withCredentials = true;
  74. }
  75. var headers = option.headers || {};
  76. // when set headers['X-Requested-With'] = null , can close default XHR header
  77. // see https://github.com/react-component/upload/issues/33
  78. if (headers['X-Requested-With'] !== null) {
  79. xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
  80. }
  81. Object.keys(headers).forEach(function (h) {
  82. if (headers[h] !== null) {
  83. xhr.setRequestHeader(h, headers[h]);
  84. }
  85. });
  86. xhr.send(formData);
  87. return {
  88. abort: function abort() {
  89. xhr.abort();
  90. }
  91. };
  92. }