Files
RedPacketRain/assets/res-native/network/HttpRequest.ts
2026-03-11 15:40:31 +08:00

314 lines
11 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.
import { game } from "cc";
import { HTTP_SITE_ID, SERVER_LIST, GAME_VER } from "../setting/ServerConfig";
import { Tools } from "../tools/Tools";
import { app } from "../../app/app";
import { CHANNELDATA } from "../data/ChannelData";
import { EDITOR } from "cc/env";
var urls: any = {}; // 当前请求地址集合
var reqparams: any = {}; // 请求参数
/**
* 登录token类全局唯一
*/
export class LoginToken{
private static instance: LoginToken | null = null;
public access_token: string = "";
public refresh_token: string = "";
public appId: string = "";
public appKey: string = "";
private constructor(){}
static get Instance(){
if(LoginToken.instance == null){
LoginToken.instance = new LoginToken();
}
return LoginToken.instance;
}
public setToken(access_token: string, refresh_token: string, appID: string, appKey: string){
this.access_token = access_token;
this.refresh_token = refresh_token;
this.appId = appID
this.appKey = appKey
}
}
/** 当前保存的token */
export const LOGIN_TOKEN : LoginToken = LoginToken.Instance;
export enum HttpEvent {
NO_NETWORK = "http_request_no_network", // 断网
UNKNOWN_ERROR = "http_request_unknown_error", // 未知错误
TIMEOUT = "http_request_timout" // 请求超时
}
export class HttpRequest {
/** 服务器地址 */
public server: string = SERVER_LIST
/** 请求超时时间 */
public timeout: number = 10000;
public lobbyUrl = ""
public setUrl (url:string) {
this.server = "http://" + url + "/"
}
/**
* HTTP GET请求
* 例:
*
* Get
var complete = function(response){
LogWrap.log(response);
}
var error = function(response){
LogWrap.log(response);
}
this.get(name, complete, error);
*/
public get(name: string, completeCallback: Function, errorCallback?: Function) {
this.sendRequest(name, null, false, completeCallback, errorCallback)
}
public getWithParams(name: string, params: any, completeCallback: Function, errorCallback?: Function) {
this.sendRequest(name, params, false, completeCallback, errorCallback)
}
public getByArraybuffer(name: string, completeCallback: Function, errorCallback?: Function) {
this.sendRequest(name, null, false, completeCallback, errorCallback, 'arraybuffer', false);
}
public getWithParamsByArraybuffer(name: string, params: any, completeCallback: Function, errorCallback?: Function) {
this.sendRequest(name, params, false, completeCallback, errorCallback, 'arraybuffer', false);
}
/**
* HTTP POST请求
* 例:
*
* Post
var param = '{"LoginCode":"donggang_dev","Password":"e10adc3949ba59abbe56e057f20f883e"}'
var complete = function(response){
var jsonData = JSON.parse(response);
var data = JSON.parse(jsonData.Data);
LogWrap.log(data.Id);
}
var error = function(response){
LogWrap.log(response);
}
this.post(name, param, complete, error);
*/
public post(name: string, params: any, completeCallback?: Function, errorCallback?: Function) {
this.sendRequest(name, params, true, completeCallback, errorCallback);
}
/** 取消请求中的请求 */
public abort(name: string) {
var xhr = urls[this.server + name];
if (xhr) {
xhr.abort();
}
}
/**
* 获得字符串形式的参数
*/
private getParamString(params: any) {
var result = "";
for (var name in params) {
let data = params[name];
if (data instanceof Object) {
for (var key in data)
result += `${key}=${data[key]}&`;
}
else {
result += `${name}=${data}&`;
}
}
return result.substring(0, result.length - 1);
}
/**
* Http请求
* @param name(string) 请求地址
* @param params(JSON) 请求参数
* @param isPost(boolen) 是否为POST方式
* @param callback(function) 请求成功回调
* @param errorCallback(function) 请求失败回调
* @param responseType(string) 响应类型
*/
private async sendRequest(
name: string,
params: any,
isPost: boolean,
completeCallback?: Function,
errorCallback?: Function,
responseType?: string,
isOpenTimeout = true,
timeout: number = this.timeout
) {
if (!name) {
console.log("请求地址不能为空");
return;
}
let url: string, newUrl: string, paramsStr: string;
if (name.toLocaleLowerCase().indexOf("http") === 0) {
url = name;
} else {
url = this.server + name;
}
if (params) {
paramsStr = this.getParamString(params);
if (url.indexOf("?") > -1)
newUrl = url + "&" + encodeURIComponent(paramsStr);
else
newUrl = url + "?" + paramsStr;
} else {
newUrl = url;
}
if (urls[newUrl] != null && reqparams[newUrl] === paramsStr!) {
console.log(`地址【${url}】已正在请求中,不能重复请求`);
return;
}
const xhr = new XMLHttpRequest();
urls[newUrl] = xhr;
reqparams[newUrl] = paramsStr!;
if (isPost) {
xhr.open("POST", url);
} else {
xhr.open("GET", newUrl);
}
if (LOGIN_TOKEN.access_token !== "") {
xhr.setRequestHeader("Authorization", "Bearer " + LOGIN_TOKEN.access_token);
}
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
// 加密设置
const time = Math.floor(Date.now() / 1000);
xhr.setRequestHeader("Lang", CHANNELDATA.lang);
if (!params) params = {};
let _params = params;
_params.appId = LOGIN_TOKEN.appId;
_params.nonceStr = Tools.getRandomStr(6);
_params.timestamp = time;
let sha256DDD: string;
try {
sha256DDD = await Tools.generateSignNative(_params, LOGIN_TOKEN.appKey);
} catch (err) {
console.error("生成签名失败:", err);
this.deleteCache(newUrl);
const data: any = { url, params, event: HttpEvent.UNKNOWN_ERROR };
if (errorCallback) errorCallback(data);
return; // 出错直接返回,避免继续执行
}
// xhr.setRequestHeader("appId", LOGIN_TOKEN.appId);
// xhr.setRequestHeader("timestamp", _params.timestamp.toString());
// xhr.setRequestHeader("signature", sha256DDD);
// xhr.setRequestHeader("nonceStr", _params.nonceStr);
// xhr.setRequestHeader("Site-Id", HTTP_SITE_ID);
// const v = app.lib.storage.get("CURR_VERSION") || "100";
// xhr.setRequestHeader("app-version-key", v.toString());
// xhr.setRequestHeader("system-key", "android");
// xhr.setRequestHeader("Client-Version", GAME_VER);
xhr.setRequestHeader("X-Domain", LOGIN_TOKEN.appId);
xhr.setRequestHeader("X-Locale", LOGIN_TOKEN.appKey);
const data: any = { url, params };
// 请求超时
if (isOpenTimeout) {
xhr.timeout = timeout;
xhr.ontimeout = () => {
this.deleteCache(newUrl);
data.event = HttpEvent.TIMEOUT;
if (errorCallback) errorCallback(data);
};
}
xhr.onloadend = () => {
if (xhr.status === 500) {
this.deleteCache(newUrl);
data.event = HttpEvent.NO_NETWORK;
if (errorCallback) errorCallback(data);
}
};
xhr.onerror = () => {
this.deleteCache(newUrl);
if (!errorCallback) return;
if (xhr.readyState === 0 || xhr.readyState === 1 || xhr.status === 0) {
data.event = HttpEvent.NO_NETWORK;
} else {
data.event = HttpEvent.UNKNOWN_ERROR;
}
errorCallback(data);
};
xhr.onreadystatechange = () => {
if (xhr.readyState !== 4) return;
this.deleteCache(newUrl);
if (xhr.status === 200) {
if (completeCallback) {
if (responseType === "arraybuffer") {
xhr.responseType = responseType;
completeCallback(xhr.response);
} else {
try {
const resp: any = JSON.parse(xhr.response);
const isDevelopment = EDITOR || (typeof window !== 'undefined' && (window.location.hostname.includes('localhost') || window.location.hostname.includes('127.0.0.1')));
if (resp.status === "success") {
if (isDevelopment) {
console.log("data:", resp.data);
}
completeCallback(resp.data);
} else {
app.manager.ui.showToast(Tools.GetLocalized(resp.message));
if (errorCallback) errorCallback(resp.data);
}
// if (Number(resp.code) === 200 || Number(resp.code) === 406) {
// const isDevelopment = EDITOR || (typeof window !== 'undefined' && (window.location.hostname.includes('localhost') || window.location.hostname.includes('127.0.0.1')));
// if (isDevelopment) {
// console.log("data:", resp.data);
// }
// completeCallback(resp.data);
// } else {
// app.manager.ui.showToast(Tools.GetLocalized(resp.msg));
// if (errorCallback) errorCallback(resp.data);
// }
} catch (error) {
console.log("解析响应失败:", error);
if (errorCallback) errorCallback({ event: HttpEvent.UNKNOWN_ERROR });
}
}
}
}else{
const resp: any = JSON.parse(xhr.response);
app.manager.ui.showToast(Tools.GetLocalized(resp.message), 3);
}
};
if (!paramsStr) {
xhr.send();
} else {
xhr.send(paramsStr!);
}
}
private deleteCache(url: string) {
delete urls[url];
delete reqparams[url];
}
}
export let httpRequest = new HttpRequest()