Files
oops-plugin-framework/assets/libs/network/HttpRequest.ts
2025-12-13 23:32:56 +08:00

318 lines
8.8 KiB
TypeScript
Raw Permalink 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.
/*
* @Author: dgflash
* @Date: 2022-09-01 18:00:28
* @LastEditors: dgflash
* @LastEditTime: 2022-09-09 18:10:50
*/
import { error, warn } from 'cc';
/**
* 使用流程文档可参考、简化与服务器对接、使用新版API体验可进入下面地址获取新版本替换network目录中的内容
* https://store.cocos.com/app/detail/5877
*/
/** 当前请求地址集合 */
const urls: any = {};
/** 请求参数 */
const reqparams: any = {};
type HttpCallback = (ret: HttpReturn) => void;
/** 请求事件 */
export enum HttpEvent {
/** 断网 */
NO_NETWORK = 'http_request_no_network',
/** 未知错误 */
UNKNOWN_ERROR = 'http_request_unknown_error',
/** 请求超时 */
TIMEOUT = 'http_request_timout'
}
/**
* HTTP请求返回值
*/
export class HttpReturn {
/** 是否请求成功 */
isSucc = false;
/** 请求返回数据 */
res?: any;
/** 请求错误数据 */
err?: any;
}
/** HTTP请求 */
export class HttpRequest {
/** 服务器地址 */
server = 'http://127.0.0.1/';
/** 请求超时时间 */
timeout = 10000;
/** 自定义请求头信息 */
private header: Map<string, string> = new Map<string, string>();
/**
* 添加自定义请求头信息
* @param name 信息名
* @param value 信息值
*/
addHeader(name: string, value: string) {
this.header.set(name, value);
}
/**
* HTTP GET请求
* @param name 协议名
* @param onComplete 请求完整回调方法
* @param params 查询参数
* @example
var param = '{"uid":12345}'
var complete = (ret: HttpReturn) => {
console.log(ret.res);
}
oops.http.getWithParams(name, complete, param);
*/
get(name: string, onComplete: HttpCallback, params: any = null) {
this.sendRequest(name, params, false, onComplete);
}
/**
* HTTP GET请求
* @param name 协议名
* @param params 查询参数
* @example
var txt = await oops.http.getAsync(name);
if (txt.isSucc) {
console.log(txt.res);
}
*/
getAsync(name: string, params: any = null): Promise<HttpReturn> {
return new Promise((resolve, reject) => {
this.sendRequest(name, params, false, (ret: HttpReturn) => {
resolve(ret);
});
});
}
/**
* HTTP GET请求非文本格式数据
* @param name 协议名
* @param onComplete 请求完整回调方法
* @param params 查询参数
*/
getByArraybuffer(name: string, onComplete: HttpCallback, params: any = null) {
this.sendRequest(name, params, false, onComplete, 'arraybuffer', false);
}
/**
* HTTP GET请求非文本格式数据
* @param name 协议名
* @param params 查询参数
* @returns Promise<any>
*/
getAsyncByArraybuffer(name: string, params: any = null): Promise<HttpReturn> {
return new Promise((resolve, reject) => {
this.sendRequest(name, params, false, (ret: HttpReturn) => {
resolve(ret);
}, 'arraybuffer', false);
});
}
/**
* HTTP POST请求
* @param name 协议名
* @param params 查询参数
* @param onComplete 请求完整回调方法
* @example
var param = '{"LoginCode":"donggang_dev","Password":"e10adc3949ba59abbe56e057f20f883e"}'
var complete = (ret: HttpReturn) => {
console.log(ret.res);
}
oops.http.post(name, complete, param);
*/
post(name: string, onComplete: HttpCallback, params: any = null) {
this.sendRequest(name, params, true, onComplete);
}
/**
* HTTP POST请求
* @param name 协议名
* @param params 查询参数
*/
postAsync(name: string, params: any = null): Promise<HttpReturn> {
return new Promise((resolve, reject) => {
this.sendRequest(name, params, true, (ret: HttpReturn) => {
resolve(ret);
});
});
}
/**
* 取消请求中的请求
* @param name 协议名
*/
abort(name: string) {
const xhr = urls[this.server + name];
if (xhr) {
xhr.abort();
}
}
/**
* 获得字符串形式的参数
* @param params 参数对象
* @returns 参数字符串
*/
private getParamString(params: any) {
let result = '';
for (const name in params) {
const data = params[name];
if (data instanceof Object) {
for (const 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 responseType(string) 响应类型
* @param isOpenTimeout(boolean) 是否触发请求超时错误
*/
private sendRequest(name: string,
params: any,
isPost: boolean,
onComplete: HttpCallback,
responseType?: string,
isOpenTimeout = true) {
if (name == null || name == '') {
error('请求地址不能为空');
return;
}
let url: string, newUrl: string, paramsStr = '';
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 + '&' + paramsStr;
else
newUrl = url + '?' + paramsStr;
}
else {
newUrl = url;
}
if (urls[newUrl] != null && reqparams[newUrl] == paramsStr) {
warn(`地址【${url}】已正在请求中,不能重复请求`);
return;
}
const xhr = new XMLHttpRequest();
// 防重复请求功能
urls[newUrl] = xhr;
reqparams[newUrl] = paramsStr;
if (isPost) {
xhr.open('POST', url);
}
else {
xhr.open('GET', newUrl);
}
// 添加自定义请求头信息
for (const [key, value] of this.header) {
xhr.setRequestHeader(key, value);
}
// xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
// xhr.setRequestHeader("Content-Type", "application/json; charset=utf-8");
const data: any = {};
data.url = url;
data.params = params;
// 请求超时
if (isOpenTimeout) {
xhr.timeout = this.timeout;
xhr.ontimeout = () => {
this.deleteCache(newUrl);
ret.isSucc = false;
ret.err = HttpEvent.TIMEOUT; // 超时
onComplete(data);
};
}
// 响应结果
var ret: HttpReturn = new HttpReturn();
xhr.onloadend = () => {
if (xhr.status == 500) {
this.deleteCache(newUrl);
ret.isSucc = false;
ret.err = HttpEvent.NO_NETWORK; // 断网
onComplete(ret);
}
};
xhr.onerror = () => {
this.deleteCache(newUrl);
ret.isSucc = false;
if (xhr.readyState == 0 || xhr.readyState == 1 || xhr.status == 0) {
ret.err = HttpEvent.NO_NETWORK; // 断网
}
else {
ret.err = HttpEvent.UNKNOWN_ERROR; // 未知错误
}
onComplete(ret);
};
xhr.onreadystatechange = () => {
if (xhr.readyState != 4) return;
this.deleteCache(newUrl);
if (xhr.status == 200 && onComplete) {
ret.isSucc = true;
if (responseType == 'arraybuffer') {
xhr.responseType = responseType; // 加载非文本格式
ret.res = xhr.response;
}
else {
ret.res = JSON.parse(xhr.response);
}
onComplete(ret);
}
};
// 发送请求
if (params == null || params == '') {
xhr.send();
}
else {
xhr.send(paramsStr);
}
}
private deleteCache(url: string) {
delete urls[url];
delete reqparams[url];
}
}