UNPKG

3.17 kBPlain TextView Raw
1// Copyright (c) .NET Foundation. All rights reserved.
2// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3
4import { AbortError, HttpError, TimeoutError } from "./Errors";
5import { HttpClient, HttpRequest, HttpResponse } from "./HttpClient";
6import { ILogger, LogLevel } from "./ILogger";
7
8export class XhrHttpClient extends HttpClient {
9 private readonly logger: ILogger;
10
11 public constructor(logger: ILogger) {
12 super();
13 this.logger = logger;
14 }
15
16 /** @inheritDoc */
17 public send(request: HttpRequest): Promise<HttpResponse> {
18 // Check that abort was not signaled before calling send
19 if (request.abortSignal && request.abortSignal.aborted) {
20 return Promise.reject(new AbortError());
21 }
22
23 if (!request.method) {
24 return Promise.reject(new Error("No method defined."));
25 }
26 if (!request.url) {
27 return Promise.reject(new Error("No url defined."));
28 }
29
30 return new Promise<HttpResponse>((resolve, reject) => {
31 const xhr = new XMLHttpRequest();
32
33 xhr.open(request.method!, request.url!, true);
34 xhr.withCredentials = true;
35 xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
36 // Explicitly setting the Content-Type header for React Native on Android platform.
37 xhr.setRequestHeader("Content-Type", "text/plain;charset=UTF-8");
38
39 const headers = request.headers;
40 if (headers) {
41 Object.keys(headers)
42 .forEach((header) => {
43 xhr.setRequestHeader(header, headers[header]);
44 });
45 }
46
47 if (request.responseType) {
48 xhr.responseType = request.responseType;
49 }
50
51 if (request.abortSignal) {
52 request.abortSignal.onabort = () => {
53 xhr.abort();
54 reject(new AbortError());
55 };
56 }
57
58 if (request.timeout) {
59 xhr.timeout = request.timeout;
60 }
61
62 xhr.onload = () => {
63 if (request.abortSignal) {
64 request.abortSignal.onabort = null;
65 }
66
67 if (xhr.status >= 200 && xhr.status < 300) {
68 resolve(new HttpResponse(xhr.status, xhr.statusText, xhr.response || xhr.responseText));
69 } else {
70 reject(new HttpError(xhr.statusText, xhr.status));
71 }
72 };
73
74 xhr.onerror = () => {
75 this.logger.log(LogLevel.Warning, `Error from HTTP request. ${xhr.status}: ${xhr.statusText}.`);
76 reject(new HttpError(xhr.statusText, xhr.status));
77 };
78
79 xhr.ontimeout = () => {
80 this.logger.log(LogLevel.Warning, `Timeout from HTTP request.`);
81 reject(new TimeoutError());
82 };
83
84 xhr.send(request.content || "");
85 });
86 }
87}
88
\No newline at end of file