squidGame/tgx-games-client/assets/module_basic/network/HttpProto.ts

193 lines
7.6 KiB
TypeScript
Raw Normal View History

2025-02-17 21:36:37 +08:00
/************************************************************************************
* FileName: HttpProto.ts
* Description:
*
* Version: v1.0.0
* Creator: Jacky(jackylvm@foxmail.com)
* CreationTime: 2024-04-22 15:09:20
* Copyright: 2021 - 2024
* ==============================================================
* History update record:
*
* ==============================================================
*************************************************************************************/
export type ParamsType = Record<string, string | number | boolean>;
export type HeadersType = Record<string, string | number | boolean>;
export type BodiesType = Record<string, any>;
export type RequestCallback = (err: Error | null, response: { type: XMLHttpRequestResponseType, data: any }) => void;
export enum HttpMethod {
GET = "GET",
POST = "POST",
}
export class HttpProto {
private _requests: string[] = [];
/**
* GET请求
* @param {string} url ,
* @param {RequestCallback} callback
* @param {ParamsType} params ,url后面的查询参数
* @param {HeadersType} headers
*/
public get(url: string, callback: RequestCallback, params: ParamsType = null, headers: HeadersType = null): void {
this.request(url, HttpMethod.GET, params, headers, {}, callback);
}
/**
* POST请求
* @param {string} url ,
* @param {RequestCallback} callback
* @param {BodiesType} bodies ,post请求用到
* @param {ParamsType} params ,url后面的查询参数
* @param {HeadersType} headers
* @param urlEncode
*/
public post(url: string, callback: RequestCallback, bodies: BodiesType | { req: BodiesType } = null, params: ParamsType = null, headers: HeadersType = null, urlEncode: boolean = true): void {
this.request(url, HttpMethod.POST, params, headers, bodies, callback, urlEncode);
}
private request(
url: string, method: HttpMethod, params: ParamsType, headers: HeadersType,
bodies: BodiesType | { req: BodiesType }, callback: RequestCallback, urlEncode: boolean = true
): void {
if (!url) {
console.error("url is null");
return;
}
let urlParams: string = this.makeURLParams(url, params);
let bodiesStr: string;
let urlBodies: any;
if (urlEncode) {
urlBodies = this.makeURLBodies(headers, bodies);
bodiesStr = urlBodies;
} else {
urlBodies = bodies;
bodiesStr = JSON.stringify(urlBodies);
}
let key: string = `${method} ${urlParams} ${bodiesStr}`;
if (this._requests.indexOf(key) > -1) {
console.warn(`${key} is in requests`);
return;
}
this._requests.push(key);
let xhr: XMLHttpRequest = new XMLHttpRequest();
xhr.timeout = 10000;
xhr.onreadystatechange = (): void => {
// readyState的状态值
// 0表示 XMLHttpRequest 实例已经生成但是实例的open()方法还没有被调用。
// 1表示open()方法已经调用但是实例的send()方法还没有调用仍然可以使用实例的setRequestHeader()方法,设定 HTTP 请求的头信息。
// 2表示实例的send()方法已经调用,并且服务器返回的头信息和状态码已经收到。
// 3表示正在接收服务器传来的数据体body 部分。这时如果实例的responseType属性等于text或者空字符串responseText属性就会包含已经收到的部分信息。
// 4表示服务器返回的数据已经完全接收或者本次接收已经失败。
if (xhr.readyState === 1) {
// 必须open方法调用后才能设置请求头
if (headers) {
for (let key in headers) {
if (key.indexOf("Content-Type") > -1 || key.indexOf("content-type") > -1) {
continue;
}
xhr.setRequestHeader(key, headers[key].toString());
}
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
} else {
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
}
}
if (xhr.readyState === 4) {
this._requests.splice(this._requests.indexOf(key), 1);
console.log(`[HttpProto>onreadystatechange:96]>>${xhr.status} ${xhr.statusText} ${xhr.responseType}`, xhr.response);
if (callback) {
if (xhr.status === 200) {
callback(null, {type: xhr.responseType, data: xhr.response});
} else {
callback(new Error(`${xhr.status} ${xhr.statusText}`), null);
}
}
}
};
xhr.ontimeout = (): void => {
this._requests.splice(this._requests.indexOf(key), 1);
if (callback) {
callback(new Error(`${xhr.status} ${xhr.statusText}`), null);
}
}
xhr.onerror = (): void => {
this._requests.splice(this._requests.indexOf(key), 1);
if (callback) {
callback(new Error(`${xhr.status} ${xhr.statusText}`), null);
}
}
xhr.onabort = (): void => {
this._requests.splice(this._requests.indexOf(key), 1);
if (callback) {
callback(new Error(`${xhr.status} ${xhr.statusText}`), null);
}
}
if (method === HttpMethod.GET) {
xhr.open(method, urlParams, true);
xhr.send();
} else {
xhr.open(method, urlParams, true);
console.log("xhr ============ ",xhr)
console.log(typeof urlBodies)
// xhr.send(urlBodies);
let b = JSON.parse(urlBodies)
console.log(typeof b)
xhr.send(b);
}
}
private makeURLParams(url: string, params: ParamsType): string {
if (params) {
let lst: string[] = [];
for (let key in params) {
lst.push(`${key}=${params[key]}`);
}
let paramsStr: string = lst.join("&");
if (url.indexOf("?") > -1) {
url += `&${paramsStr}`;
} else {
if (paramsStr.length > 0) {
if (!url.endsWith("/")) {
url += "/";
}
url += `?${paramsStr}`;
}
}
}
return url;
}
private makeURLBodies(headers: HeadersType, bodies: BodiesType): string {
let contentType: string = "application/json";
if (headers) {
contentType = headers["Content-Type"] as string;
}
let body: string = "";
if (bodies) {
if (contentType === "application/json") {
body = JSON.stringify(bodies);
} else if (contentType === "application/x-www-form-urlencoded") {
let lst: string[] = [];
for (let key in bodies) {
lst.push(`${key}=${bodies[key]}`);
}
body = lst.join("&");
}
}
return body;
}
}