网络请求XMLHttpRequest的扩展¶
这个类包含了http的get和post请求以及数据返回后的处理,采用的是callback的形式,当然也可以转换为使用promise来做,如有需要请自行修改
export class HttpRequest
{
private static _inst:HttpRequest;
private constructor()
{
}
/** 获取单例*/
static getInst():HttpRequest
{
if(!this._inst)
{
this._inst = new HttpRequest();
}
return this._inst;
}
/** get请求*/
doGet(url:string, headers, params, cb:handler)
{
if(params)
{
if(url.indexOf("?") == -1)
{
url += "?";
}
url += this.getQueryString(params);
}
this.doHttp(url, headers, null, "GET", cb);
}
/** post 请求*/
doPost(url:string, headers, params, cb:handler)
{
this.doHttp(url, headers, params, "POST", cb);
}
/** 最终完整的请求*/
private doHttp(url:string, headers, params, method:string, cb:handler)
{
const xhr = new XMLHttpRequest();
xhr.responseType = "text";
xhr.onreadystatechange = this.onReadyStateChange.bind(this, xhr, cb);
xhr.ontimeout = this.onTimeout.bind(this, xhr, url);
xhr.onerror = this.onError.bind(this, xhr, url);
xhr.onabort = this.onAbort.bind(this, xhr, url);
cc.log(`HttpRequest, doHttp url=${url}, method=${method}, parmas=${params}`)
xhr.open(method, url, true);
if(headers)
{
this.setHttpHeaders(xhr, headers);
}
if (cc.sys.isNative)
{
this.setHttpHeaders(xhr, {"Accept-Encoding": "gzip,deflate"});
}
if(params && typeof params === "object")
{
params = JSON.stringify(params);
}
xhr.send(params);
}
/** 正常返回的处理*/
private onReadyStateChange(xhr:XMLHttpRequest, cb:handler)
{
cc.log(`HttpRequest, onReadyStateChange, readyState=${xhr.readyState}, status=${xhr.status}`);
if(xhr.readyState === 4 && xhr.status >= 200 && xhr.status < 300)
{
cc.log(`HttpRequest, onReadyStateChange, responseText=${xhr.responseText}`);
let data;
let code = HttpCode.kUnknown;
const response = JSON.parse(xhr.responseText);
if(response && response.code)
{
code = response.code;
data = response.content;
}
else
{
code = HttpCode.kSuccess;
data = response;
}
this.notifyCallback(cb, code, data);
this.removeXhrEvent(xhr);
}
}
/** 超时的处理*/
private onTimeout(xhr:XMLHttpRequest, url:string)
{
cc.warn(`${url}, request ontimeout`);
this.removeXhrEvent(xhr);
}
/** 错误的处理*/
private onError(xhr:XMLHttpRequest, url:string)
{
cc.warn(`${url}, request onerror`);
this.removeXhrEvent(xhr);
}
/** 中断的处理*/
private onAbort(xhr:XMLHttpRequest, url:string)
{
cc.warn(`${url}, request onabort`);
this.removeXhrEvent(xhr);
}
/** 移除监听事件*/
private removeXhrEvent(xhr:XMLHttpRequest)
{
xhr.ontimeout = null;
xhr.onerror = null;
xhr.onabort = null;
xhr.onreadystatechange = null;
}
/** 返回数据*/
private notifyCallback(cb:handler, code:number, data?)
{
if(cb)
{
cb.exec(code, data);
}
}
/** 设置http请求的头部*/
private setHttpHeaders(xhr:XMLHttpRequest, headers)
{
for(let key in headers)
{
xhr.setRequestHeader(key, headers[key]);
}
}
/** 拼接请求的参数*/
private getQueryString(params)
{
const tmps:string[] = [];
for(let key in params)
{
tmps.push(`${key}=${params[key]}`);
}
return tmps.join("&");
}
}
/** 状态码*/
export enum HttpCode {
kSuccess = 0,
kTimeout = 10000,
kUnknown = 10001,
kSessionTimeout = -8,
kIAmInBlocklist = -3013,
kUserIsInMyBlocklist = -3014
}
/**用于绑定回调函数this指针*/
export class handler
{
private cb:Function;
private host:any;
private args:any[];
constructor(){}
init(cb:Function, host = null, ...args)
{
this.cb = cb;
this.host = host;
this.args = args;
}
exec(...extras)
{
this.cb.apply(this.host, this.args.concat(extras));
}
}