xhr.js 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. import { BaseClient, BaseResponse } from './base.js';
  2. import { AbortError } from '../../utils.js';
  3. class XHRResponse extends BaseResponse {
  4. /**
  5. * BaseResponse facade for XMLHttpRequest
  6. * @param {XMLHttpRequest} xhr
  7. * @param {ArrayBuffer} data
  8. */
  9. constructor(xhr, data) {
  10. super();
  11. this.xhr = xhr;
  12. this.data = data;
  13. }
  14. get status() {
  15. return this.xhr.status;
  16. }
  17. getHeader(name) {
  18. return this.xhr.getResponseHeader(name);
  19. }
  20. async getData() {
  21. return this.data;
  22. }
  23. }
  24. export class XHRClient extends BaseClient {
  25. constructRequest(headers, signal) {
  26. return new Promise((resolve, reject) => {
  27. const xhr = new XMLHttpRequest();
  28. xhr.open('GET', this.url);
  29. xhr.responseType = 'arraybuffer';
  30. for (const [key, value] of Object.entries(headers)) {
  31. xhr.setRequestHeader(key, value);
  32. }
  33. // hook signals
  34. xhr.onload = () => {
  35. const data = xhr.response;
  36. resolve(new XHRResponse(xhr, data));
  37. };
  38. xhr.onerror = reject;
  39. xhr.onabort = () => reject(new AbortError('Request aborted'));
  40. xhr.send();
  41. if (signal) {
  42. if (signal.aborted) {
  43. xhr.abort();
  44. }
  45. signal.addEventListener('abort', () => xhr.abort());
  46. }
  47. });
  48. }
  49. async request({ headers, signal } = {}) {
  50. const response = await this.constructRequest(headers, signal);
  51. return response;
  52. }
  53. }