зеркало из https://github.com/Azure/ms-rest-js.git
Use axios instead of fetch
This commit is contained in:
Родитель
cd33133617
Коммит
11896a2ce9
|
@ -3,17 +3,28 @@
|
|||
|
||||
import * as FormData from "form-data";
|
||||
import * as xml2js from "isomorphic-xml2js";
|
||||
import axiosFactory, { AxiosResponse, AxiosError, AxiosRequestConfig } from "axios";
|
||||
import { HttpClient } from "./httpClient";
|
||||
import { HttpOperationResponse } from "./httpOperationResponse";
|
||||
import { WebResource } from "./webResource";
|
||||
import { RestError } from "./restError";
|
||||
import { HttpHeaders } from "./httpHeaders";
|
||||
import { isNode } from "./util/utils";
|
||||
import * as tough from "tough-cookie";
|
||||
|
||||
const axios = axiosFactory.create();
|
||||
|
||||
if (isNode) {
|
||||
// Workaround for https://github.com/axios/axios/issues/1158
|
||||
axios.interceptors.request.use(config => ({ ...config, method: config.method && config.method.toUpperCase() }));
|
||||
}
|
||||
|
||||
/**
|
||||
* A HttpClient implementation that uses fetch to send HTTP requests.
|
||||
*/
|
||||
export class FetchHttpClient implements HttpClient {
|
||||
private readonly cookieJar = isNode ? new tough.CookieJar() : null;
|
||||
|
||||
public async sendRequest(httpRequest: WebResource): Promise<HttpOperationResponse> {
|
||||
if (!httpRequest) {
|
||||
return Promise.reject(new Error("options (WebResource) cannot be null or undefined and must be of type object."));
|
||||
|
@ -59,43 +70,76 @@ export class FetchHttpClient implements HttpClient {
|
|||
}
|
||||
}
|
||||
|
||||
// allow cross-origin cookies in browser
|
||||
(httpRequest as any).credentials = "include";
|
||||
if (this.cookieJar) {
|
||||
const cookieString = await new Promise<string>((resolve, reject) => {
|
||||
this.cookieJar!.getCookieString(httpRequest.url, (err, cookie) => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
resolve(cookie);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
let res: Response;
|
||||
try {
|
||||
res = await myFetch(httpRequest.url, httpRequest);
|
||||
} catch (err) {
|
||||
return Promise.reject(err);
|
||||
httpRequest.headers["Cookie"] = cookieString;
|
||||
}
|
||||
|
||||
let res: AxiosResponse;
|
||||
try {
|
||||
const config: AxiosRequestConfig = {
|
||||
method: httpRequest.method,
|
||||
url: httpRequest.url,
|
||||
headers: httpRequest.headers,
|
||||
data: httpRequest.body,
|
||||
transformResponse: undefined,
|
||||
validateStatus: () => true,
|
||||
withCredentials: true,
|
||||
responseType: httpRequest.rawResponse ? (isNode ? "stream" : "blob") : "text"
|
||||
};
|
||||
res = await axios(config);
|
||||
} catch (err) {
|
||||
const axiosErr = err as AxiosError;
|
||||
throw new RestError(axiosErr.message, "REQUEST_SEND_ERROR", undefined, httpRequest);
|
||||
}
|
||||
|
||||
const headers = new HttpHeaders();
|
||||
res.headers.forEach((value: string, name: string) => {
|
||||
headers.set(name, value);
|
||||
});
|
||||
const headers = new HttpHeaders(res.headers);
|
||||
|
||||
const operationResponse: HttpOperationResponse = {
|
||||
request: httpRequest,
|
||||
status: res.status,
|
||||
headers,
|
||||
readableStreamBody: isNode ? res.body as any : undefined,
|
||||
blobBody: isNode ? undefined : () => res.blob()
|
||||
readableStreamBody: httpRequest.rawResponse && isNode ? res.data as any : undefined,
|
||||
blobBody: !httpRequest.rawResponse || isNode ? undefined : () => res.data
|
||||
};
|
||||
|
||||
if (this.cookieJar) {
|
||||
const setCookieHeader = operationResponse.headers.get("Set-Cookie");
|
||||
if (setCookieHeader != undefined) {
|
||||
await new Promise((resolve, reject) => {
|
||||
this.cookieJar!.setCookie(setCookieHeader, httpRequest.url, (err) => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (!httpRequest.rawResponse) {
|
||||
try {
|
||||
operationResponse.bodyAsText = await res.text();
|
||||
operationResponse.bodyAsText = res.data;
|
||||
} catch (err) {
|
||||
const msg = `Error "${err}" occured while converting the raw response body into string.`;
|
||||
const errCode = err.code || "RAWTEXT_CONVERSION_ERROR";
|
||||
const e = new RestError(msg, errCode, res.status, httpRequest, operationResponse, res.body);
|
||||
const e = new RestError(msg, errCode, res.status, httpRequest, operationResponse, res.data);
|
||||
return Promise.reject(e);
|
||||
}
|
||||
|
||||
try {
|
||||
if (operationResponse.bodyAsText) {
|
||||
const contentType = res.headers.get("Content-Type")!;
|
||||
const contentType = operationResponse.headers.get("Content-Type");
|
||||
if (contentType === "application/xml" || contentType === "text/xml") {
|
||||
const xmlParser = new xml2js.Parser(XML2JS_PARSER_OPTS);
|
||||
const parseString = new Promise(function (resolve: (result: any) => void, reject: (err: any) => void) {
|
||||
|
@ -124,26 +168,6 @@ export class FetchHttpClient implements HttpClient {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides the fetch() method based on the environment.
|
||||
* @returns {fetch} fetch - The fetch() method available in the environment to make requests
|
||||
*/
|
||||
export function getFetch(): Function {
|
||||
// using window.Fetch in Edge gives a TypeMismatchError
|
||||
// (https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/8546263/).
|
||||
// Hence we will be using the fetch-ponyfill for Edge.
|
||||
if (typeof window !== "undefined" && window.fetch && window.navigator &&
|
||||
window.navigator.userAgent && window.navigator.userAgent.indexOf("Edge/") === -1) {
|
||||
return window.fetch.bind(window);
|
||||
}
|
||||
return require("fetch-ponyfill")({ useCookie: true }).fetch;
|
||||
}
|
||||
|
||||
/**
|
||||
* A constant that provides the fetch() method based on the environment.
|
||||
*/
|
||||
export const myFetch = getFetch();
|
||||
|
||||
const XML2JS_PARSER_OPTS: xml2js.OptionsV2 = {
|
||||
explicitArray: false,
|
||||
explicitCharkey: false,
|
||||
|
|
11
package.json
11
package.json
|
@ -29,25 +29,26 @@
|
|||
"types": "./typings/lib/msRest.d.ts",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/axios": "^0.14.0",
|
||||
"@types/express": "^4.11.1",
|
||||
"@types/form-data": "^2.2.1",
|
||||
"@types/is-stream": "^1.1.0",
|
||||
"@types/node": "^9.4.6",
|
||||
"@types/node-fetch": "^1.6.7",
|
||||
"@types/uuid": "^3.4.3",
|
||||
"fetch-cookie": "^0.7.0",
|
||||
"fetch-ponyfill": "amarzavery/fetch-ponyfill#master",
|
||||
"axios": "^0.18.0",
|
||||
"form-data": "^2.3.2",
|
||||
"is-buffer": "^2.0.0",
|
||||
"is-stream": "^1.1.0",
|
||||
"isomorphic-xml2js": "^0.0.3",
|
||||
"tough-cookie": "^2.3.4",
|
||||
"url-parse": "^1.2.0",
|
||||
"uuid": "^3.2.1",
|
||||
"isomorphic-xml2js": "^0.0.3"
|
||||
"uuid": "^3.2.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/glob": "^5.0.35",
|
||||
"@types/mocha": "^5.2.0",
|
||||
"@types/should": "^8.1.30",
|
||||
"@types/tough-cookie": "^2.3.3",
|
||||
"@types/url-parse": "^1.1.0",
|
||||
"@types/webpack": "^4.1.3",
|
||||
"@types/webpack-dev-middleware": "^2.0.1",
|
||||
|
|
|
@ -25,7 +25,7 @@ const config: webpack.Configuration = {
|
|||
},
|
||||
node: {
|
||||
fs: false,
|
||||
net: false,
|
||||
net: "empty", // TODO: create wrapper package for tough-cookie and change this back to "false"
|
||||
path: false,
|
||||
dns: false,
|
||||
tls: false,
|
||||
|
|
|
@ -31,7 +31,7 @@ const config = {
|
|||
},
|
||||
node: {
|
||||
fs: false,
|
||||
net: false,
|
||||
net: "empty",
|
||||
path: false,
|
||||
dns: false,
|
||||
tls: false,
|
||||
|
|
Загрузка…
Ссылка в новой задаче