XhrHttpClient.js 3.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. // Licensed to the .NET Foundation under one or more agreements.
  2. // The .NET Foundation licenses this file to you under the MIT license.
  3. import { AbortError, HttpError, TimeoutError } from "./Errors";
  4. import { HttpClient, HttpResponse } from "./HttpClient";
  5. import { LogLevel } from "./ILogger";
  6. import { isArrayBuffer } from "./Utils";
  7. export class XhrHttpClient extends HttpClient {
  8. constructor(logger) {
  9. super();
  10. this._logger = logger;
  11. }
  12. /** @inheritDoc */
  13. send(request) {
  14. // Check that abort was not signaled before calling send
  15. if (request.abortSignal && request.abortSignal.aborted) {
  16. return Promise.reject(new AbortError());
  17. }
  18. if (!request.method) {
  19. return Promise.reject(new Error("No method defined."));
  20. }
  21. if (!request.url) {
  22. return Promise.reject(new Error("No url defined."));
  23. }
  24. return new Promise((resolve, reject) => {
  25. const xhr = new XMLHttpRequest();
  26. xhr.open(request.method, request.url, true);
  27. xhr.withCredentials = request.withCredentials === undefined ? true : request.withCredentials;
  28. xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
  29. if (request.content === "") {
  30. request.content = undefined;
  31. }
  32. if (request.content) {
  33. // Explicitly setting the Content-Type header for React Native on Android platform.
  34. if (isArrayBuffer(request.content)) {
  35. xhr.setRequestHeader("Content-Type", "application/octet-stream");
  36. }
  37. else {
  38. xhr.setRequestHeader("Content-Type", "text/plain;charset=UTF-8");
  39. }
  40. }
  41. const headers = request.headers;
  42. if (headers) {
  43. Object.keys(headers)
  44. .forEach((header) => {
  45. xhr.setRequestHeader(header, headers[header]);
  46. });
  47. }
  48. if (request.responseType) {
  49. xhr.responseType = request.responseType;
  50. }
  51. if (request.abortSignal) {
  52. request.abortSignal.onabort = () => {
  53. xhr.abort();
  54. reject(new AbortError());
  55. };
  56. }
  57. if (request.timeout) {
  58. xhr.timeout = request.timeout;
  59. }
  60. xhr.onload = () => {
  61. if (request.abortSignal) {
  62. request.abortSignal.onabort = null;
  63. }
  64. if (xhr.status >= 200 && xhr.status < 300) {
  65. resolve(new HttpResponse(xhr.status, xhr.statusText, xhr.response || xhr.responseText));
  66. }
  67. else {
  68. reject(new HttpError(xhr.response || xhr.responseText || xhr.statusText, xhr.status));
  69. }
  70. };
  71. xhr.onerror = () => {
  72. this._logger.log(LogLevel.Warning, `Error from HTTP request. ${xhr.status}: ${xhr.statusText}.`);
  73. reject(new HttpError(xhr.statusText, xhr.status));
  74. };
  75. xhr.ontimeout = () => {
  76. this._logger.log(LogLevel.Warning, `Timeout from HTTP request.`);
  77. reject(new TimeoutError());
  78. };
  79. xhr.send(request.content);
  80. });
  81. }
  82. }
  83. //# sourceMappingURL=XhrHttpClient.js.map