egg_tools/dist/netTool.js

304 lines
10 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import loggerIns from "./logger";
export class NetError extends Error {
code;
message;
httpStatus;
constructor({ code, message, httpStatus }) {
super(message);
this.code = code;
this.message = message;
this.httpStatus = httpStatus;
}
}
/**
* 网络工具类提供发送HTTP请求的方法。
*/
class NetToolBase {
prefix;
headers;
getHeaders;
logger;
requestId;
/**
* 创建一个网络工具类实例。
*
* @param {Object} params - 构造函数参数。
* @param {string} [params.prefix] - URL前缀。
* @param {any} [params.headers] - 默认请求头。
* @param {Function} [params.getHeaders] - 获取请求头的方法。
* @param {string} [params.requestId] - 请求ID。
*/
constructor({ prefix, headers, getHeaders, requestId, } = {}) {
this.prefix = prefix || "";
this.headers = headers || {};
this.getHeaders = getHeaders || (() => ({}));
this.requestId = requestId || "";
this.logger = loggerIns.child({ requestId });
}
/**
* 记录响应详情并返回响应日志对象。
* @param response - 响应对象。
* @param method - 请求使用的HTTP方法。
* @param headers - 请求头。
* @param requestBody - 请求体。
* @param responseBody - 响应体。
* @returns 响应日志对象。
*/
logResponse(response, method, headers, requestBody, responseBody) {
const responseLog = {
ok: response.ok,
status: response.status,
statusText: response.statusText,
url: response.url,
method: method,
requestHeaders: headers,
responseHeaders: response.headers,
requestBody,
responseBody,
};
this.logger.http(JSON.stringify(responseLog, null, 2));
return responseLog;
}
/**
* 发送网络请求并返回一个解析为响应数据的Promise。
* @param url - 要发送请求的URL。
* @param method - 请求使用的HTTP方法。
* @param queryParams - 要包含在URL中的查询参数。
* @param payload - 请求的有效负载数据。
* @param additionalHeaders - 要包含在请求中的附加头。
* @returns 一个解析为响应数据的Promise。
* @throws 如果网络响应不成功或存在解析错误,则抛出错误。
*/
async request({ url, method, queryParams, payload, additionalHeaders, }) {
// 拼接完整的URL
let fullUrl = `${this.prefix}${url}`;
if (queryParams) {
if (typeof queryParams === "string") {
fullUrl = `${fullUrl}?${queryParams}`;
}
else {
const queryString = new URLSearchParams(queryParams).toString();
if (queryString)
fullUrl = `${fullUrl}?${queryString}`;
}
}
// 设置请求头
const headers = {
...this.headers,
...(await this.getHeaders()),
...additionalHeaders,
};
// 设置请求Header
if (!(payload instanceof FormData)) {
headers["Content-Type"] = "application/json";
}
// 处理请求数据
const body = payload instanceof FormData ? payload : JSON.stringify(payload);
// 发送请求
const res = await fetch(fullUrl, {
method,
body,
headers,
});
// 获取响应数据
let resData = null;
let resText = "";
try {
resText = await res.text();
resData = JSON.parse(resText);
}
catch {
/* empty */
}
// 记录响应
this.logResponse(res, method, headers, payload, resData || resText);
if (!res.ok) {
if (resData?.message || resData?.msg) {
throw new NetError({
httpStatus: res.status,
code: resData?.code,
message: resData?.message || resData?.msg,
});
}
throw new NetError({
httpStatus: res.status,
code: res.status,
message: resText || "网络响应异常",
});
}
// http 错误码正常,但解析异常
if (!resData) {
throw new NetError({
httpStatus: res.status,
code: 1,
message: "解析响应数据异常",
});
}
// 响应数据异常
if ("code" in resData && resData.code !== 0) {
throw new NetError({
httpStatus: res.status,
code: resData.code,
message: resData.message || resData.msg || "网络请求失败",
});
}
return resData;
}
/**
* 发送GET请求并返回一个解析为响应数据的Promise。
*
* @param url - 要发送请求的URL。
* @param queryParams - 要包含在URL中的查询参数。
* @param additionalHeaders - 要包含在请求中的附加头。
* @returns 一个解析为响应数据的Promise。
*/
get(url, queryParams, additionalHeaders) {
return this.request({ url, method: "get", queryParams, additionalHeaders });
}
/**
* 发送POST请求并返回一个解析为响应数据的Promise。
*
* @param url - 要发送请求的URL。
* @param payload - 请求的有效负载数据。
* @param queryParams - 要包含在URL中的查询参数。
* @param additionalHeaders - 要包含在请求中的附加头。
* @returns 一个解析为响应数据的Promise。
*/
post(url, payload, queryParams, additionalHeaders) {
return this.request({
url,
method: "post",
payload,
queryParams,
additionalHeaders,
});
}
/**
* 发送PUT请求并返回一个解析为响应数据的Promise。
*
* @param url - 要发送请求的URL。
* @param payload - 请求的有效负载数据。
* @param queryParams - 要包含在URL中的查询参数。
* @param additionalHeaders - 要包含在请求中的附加头。
* @returns 一个解析为响应数据的Promise。
*/
put(url, payload, queryParams, additionalHeaders) {
return this.request({
url,
method: "put",
payload,
queryParams,
additionalHeaders,
});
}
/**
* 发送DELETE请求并返回一个解析为响应数据的Promise。
*
* @param url - 要发送请求的URL。
* @param payload - 请求的有效负载数据。
* @param queryParams - 要包含在URL中的查询参数。
* @param additionalHeaders - 要包含在请求中的附加头。
* @returns 一个解析为响应数据的Promise。
*/
del(url, payload, queryParams, additionalHeaders) {
return this.request({
url,
method: "delete",
payload,
queryParams,
additionalHeaders,
});
}
/**
* 发送PATCH请求并返回一个解析为响应数据的Promise。
*
* @param url - 要发送请求的URL。
* @param payload - 请求的有效负载数据。
* @param queryParams - 要包含在URL中的查询参数。
* @param additionalHeaders - 要包含在请求中的附加头。
* @returns 一个解析为响应数据的Promise。
*/
patch(url, payload, queryParams, additionalHeaders) {
return this.request({
url,
method: "patch",
payload,
queryParams,
additionalHeaders,
});
}
}
class NetTool extends NetToolBase {
request({ url, method, queryParams, payload, additionalHeaders, }) {
return super.request({
url,
method,
queryParams,
payload,
additionalHeaders,
});
}
get(url, queryParams, additionalHeaders) {
return super.get(url, queryParams, additionalHeaders);
}
post(url, payload, queryParams, additionalHeaders) {
return super.post(url, payload, queryParams, additionalHeaders);
}
put(url, payload, queryParams, additionalHeaders) {
return super.put(url, payload, queryParams, additionalHeaders);
}
del(url, payload, queryParams, additionalHeaders) {
return super.del(url, payload, queryParams, additionalHeaders);
}
patch(url, payload, queryParams, additionalHeaders) {
return super.patch(url, payload, queryParams, additionalHeaders);
}
/**
* 创建一个表示400 Bad Request的响应对象。
*
* @param message - 错误消息。
* @returns 一个表示400 Bad Request的响应对象。
*/
badRequest(message) {
this.logger.error(`return a bad request response: ${message}`);
return Response.json({ code: 400, message, requestId: this.requestId }, { status: 400 });
}
/**
* 创建一个表示404 Not Found的响应对象。
*
* @param message - 错误消息。
* @returns 一个表示404 Not Found的响应对象。
*/
notFound(message) {
this.logger.error(`return a not found response: ${message}`);
return Response.json({ code: 404, message, requestId: this.requestId }, { status: 404 });
}
/**
* 创建一个表示500 Internal Server Error的响应对象。
*
* @param message - 错误消息。
* @param data - 错误数据。
* @returns 一个表示500 Internal Server Error的响应对象。
*/
serverError(message, data) {
this.logger.error(`return a server error response: ${message}`);
return Response.json({ code: 500, message, data, requestId: this.requestId }, { status: 500 });
}
/**
* 创建一个表示200 OK的响应对象。
*
* @param data - 响应数据。
* @returns 一个表示200 OK的响应对象。
*/
ok(data) {
this.logger.info(`return a ok response: ${JSON.stringify(data)}`);
return Response.json({
code: 0,
message: "success",
data,
requestId: this.requestId,
});
}
}
export { NetTool, NetToolBase };