123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124 |
- import { AjaxRequest, AjaxResponseType } from './types';
- import { getXHRResponse } from './getXHRResponse';
- /**
- * A normalized response from an AJAX request. To get the data from the response,
- * you will want to read the `response` property.
- *
- * - DO NOT create instances of this class directly.
- * - DO NOT subclass this class.
- *
- * It is advised not to hold this object in memory, as it has a reference to
- * the original XHR used to make the request, as well as properties containing
- * request and response data.
- *
- * @see {@link ajax}
- * @see {@link AjaxConfig}
- */
- export class AjaxResponse<T> {
- /** The HTTP status code */
- readonly status: number;
- /**
- * The response data, if any. Note that this will automatically be converted to the proper type
- */
- readonly response: T;
- /**
- * The responseType set on the request. (For example: `""`, `"arraybuffer"`, `"blob"`, `"document"`, `"json"`, or `"text"`)
- * @deprecated There isn't much reason to examine this. It's the same responseType set (or defaulted) on the ajax config.
- * If you really need to examine this value, you can check it on the `request` or the `xhr`. Will be removed in v8.
- */
- readonly responseType: XMLHttpRequestResponseType;
- /**
- * The total number of bytes loaded so far. To be used with {@link total} while
- * calculating progress. (You will want to set {@link includeDownloadProgress} or
- * {@link includeDownloadProgress})
- */
- readonly loaded: number;
- /**
- * The total number of bytes to be loaded. To be used with {@link loaded} while
- * calculating progress. (You will want to set {@link includeDownloadProgress} or
- * {@link includeDownloadProgress})
- */
- readonly total: number;
- /**
- * A dictionary of the response headers.
- */
- readonly responseHeaders: Record<string, string>;
- /**
- * A normalized response from an AJAX request. To get the data from the response,
- * you will want to read the `response` property.
- *
- * - DO NOT create instances of this class directly.
- * - DO NOT subclass this class.
- *
- * @param originalEvent The original event object from the XHR `onload` event.
- * @param xhr The `XMLHttpRequest` object used to make the request. This is useful for examining status code, etc.
- * @param request The request settings used to make the HTTP request.
- * @param type The type of the event emitted by the {@link ajax} Observable
- */
- constructor(
- /**
- * The original event object from the raw XHR event.
- */
- public readonly originalEvent: ProgressEvent,
- /**
- * The XMLHttpRequest object used to make the request.
- * NOTE: It is advised not to hold this in memory, as it will retain references to all of it's event handlers
- * and many other things related to the request.
- */
- public readonly xhr: XMLHttpRequest,
- /**
- * The request parameters used to make the HTTP request.
- */
- public readonly request: AjaxRequest,
- /**
- * The event type. This can be used to discern between different events
- * if you're using progress events with {@link includeDownloadProgress} or
- * {@link includeUploadProgress} settings in {@link AjaxConfig}.
- *
- * The event type consists of two parts: the {@link AjaxDirection} and the
- * the event type. Merged with `_`, they form the `type` string. The
- * direction can be an `upload` or a `download` direction, while an event can
- * be `loadstart`, `progress` or `load`.
- *
- * `download_load` is the type of event when download has finished and the
- * response is available.
- */
- public readonly type: AjaxResponseType = 'download_load'
- ) {
- const { status, responseType } = xhr;
- this.status = status ?? 0;
- this.responseType = responseType ?? '';
- // Parse the response headers in advance for the user. There's really
- // not a great way to get all of them. So we need to parse the header string
- // we get back. It comes in a simple enough format:
- //
- // header-name: value here
- // content-type: application/json
- // other-header-here: some, other, values, or, whatever
- const allHeaders = xhr.getAllResponseHeaders();
- this.responseHeaders = allHeaders
- ? // Split the header text into lines
- allHeaders.split('\n').reduce((headers: Record<string, string>, line) => {
- // Split the lines on the first ": " as
- // "key: value". Note that the value could
- // technically have a ": " in it.
- const index = line.indexOf(': ');
- headers[line.slice(0, index)] = line.slice(index + 2);
- return headers;
- }, {})
- : {};
- this.response = getXHRResponse(xhr);
- const { loaded, total } = originalEvent;
- this.loaded = loaded;
- this.total = total;
- }
- }
|