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

193 lines
7.6 KiB
TypeScript
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.

/************************************************************************************
* 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;
}
}