Egret 中封装了 XMLHttpRequest 进行异步的数据交互。
基本过程
HTTP 通信机制都要经过如下的几个步骤:
建立TCP连接.
Web浏览器向Web服务器发送请求命令.
Web浏览器发送请求头信息
Web服务器应答
Web服务器发送应答头信息
Web服务器向浏览器发送数据
Web服务器关闭TCP连接(如果请求头部设置了Connection:keep-alive将保持连接状态仍然打开).
发送请求
发送请求有GET和POST方法:
egret.HttpMethod.GET
egret.HttpMethod.POST
Egret 使用 HttpRequest 类发送 HTTP 请求。可以指定请求的方法为 GET 或者 POST 。可以通过监听加载事件来检测服务器端的响应。使用 HttpRequest 来发送请求的过程如下:
- 实例化一个 HttpRequest 对象。
- 设置它的响应类型 responseType。
- 通过 open 方法初始化请求一个对象,初始化请求地址和请求类型。
- 通过 setRequestHeader 设置请求头信息。如果是POST带参数的请求这一步很重要,需要告诉服务端请求的参数格式,而且这一步需要在 open 之后执行。
- 通过 send 方法发送请求,如果是 post 方法可以传入参数。
- 添加监听,监听服务器端的响应,包括进度事件和请求成功和失败事件。
private createGameScene() {
//实例化一个HttpRequest对象
var request = new egret.HttpRequest();
//设置响应类型responseType
request.responseType = egret.HttpResponseType.TEXT;
//open方法初始化一个请求对象,参数为请求为请求地址和请求类型
request.open("http://httpbin.org/get",egret.HttpMethod.GET);
//设置请求头信息。如果是POST带参数的请求这一步很重要,需要告诉服务端请求的参数格式,而且这一步需要在 open 之后执行
request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
//send发送请求,如果是 post 方法可以传入参数。
request.send();
//监听请求事件
//监听请求成功
request.addEventListener(egret.Event.COMPLETE,this.onGetComplete,this);
//监听请求失败
request.addEventListener(egret.IOErrorEvent.IO_ERROR,this.onGetIOError,this);
//监听请求进度
request.addEventListener(egret.ProgressEvent.PROGRESS,this.onGetProgress,this);
}
//请求成功
private onGetComplete(event:egret.Event):void{
//获取请求对象
var request = <egret.HttpRequest>event.currentTarget;
//获取返回的信息
var data=request.response;
console.log(data)
}
//请求失败
private onGetIOError(event:egret.Event):void{
console.log("error :" + event);
}
//请求进度
private onGetProgress(event:egret.Event):void{
console.log("progress : " + Math.floor(100*(event as any).bytesLoaded/(<any>event).bytesTotal) + "%");
}
发送带参数的请求
发送数据的格式:在 HTTP 客户端发送的数据,一般以key和value的形式组成,多个数据之间用&相连。拼接之后形成如下的形式
key1=value1&key2=valueP2
通过 GET 方法发送的参数会加到 URL 的后面拼接起来,并以?分隔。POST 方法发送的参数需要先设置 HTTP 请求的头信息,告诉服务端是以什么样的形式来发送的数据。我们最常用的就是application/x-www-form-urlencoded,表示我们以key和value方式来格式化参数。服务端也可以用同样的方法来取到参数。
首先是 GET 请求,GET 请求需要将参数拼接到 URL 后面实现。其中 URL 和 参数之间需要用 ? 链接
GET方式:
//拼接参数
var params = "?p1=getP1&p2=getP2";
var request = new egret.HttpRequest();
request.responseType = egret.HttpResponseType.TEXT;
//将参数拼接到url
request.open("php/get_test.php"+params,egret.HttpMethod.GET);
request.send();
POST方式:
发送 POST 请求. 需要注意的是发送 POST 请求需要将参数放到send方法的参数中发送出去。并且要设置其响应头,在我们的例子中使用key value 的方式来格式化参数,这里需要设置响应头Content-Type为application/x-www-form-urlencoded
//拼接参数
var params = "p1=postP1&p2=postP2";
var request = new egret.HttpRequest();
request.responseType = egret.HttpResponseType.TEXT;
request.open("php/post_test.php",egret.HttpMethod.POST);
//设置响应头
request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
//发送参数
request.send(params);
加载位图文件
Egret 提供了 ImageLoader 类,用于加载位图文件。
例如 ImageLoader 类通过如下代码加载位于 ‘resource/egret.png’ 的图片:
var imgLoader:egret.ImageLoader = new egret.ImageLoader;
imgLoader.once( egret.Event.COMPLETE, this.imgLoadHandler, this );
imgLoader.load( "resource/egret.png" );
//在所定义的回调事件中,可以用下面的方式获取该图片对应的 BitmapData,并以此来创建位图:
public imgLoadHandler( evt:egret.Event ):void{
var loader:egret.ImageLoader = evt.currentTarget;
var bmd:egret.BitmapData = loader.data;
var bmp:egret.Bitmap = new egret.Bitmap( bmd );
this.addChild(bmp);
}
跨域处理:
1.服务器设置访问权限
2.可以通过尝试修改 imgLoader.crossOrigin = 'anonymous' 来以匿名的方式访问。不过在使用 texture.toDataURL 时会报跨域问题。
3.Webgl 渲染下,暂不支持跨域图片处理。
加载文本
HttpRequest 对象最核心的方法就是 open() 和 send() 。 open() 方法接收该请求所要访问的URL。 作为可选项还可以传入加载方式,这个参数通常用 HttpMethod 取常量,默认是最常用的 GET 方式。
在加载完成时,通过 HttpRequest 对象的 response 属性来获取返回的数据。
var url = "resource/config/description.json";
var request:egret.HttpRequest = new egret.HttpRequest();
var respHandler = function( evt:egret.Event ):void{
switch ( evt.type ){
case egret.Event.COMPLETE:
var request:egret.HttpRequest = evt.currentTarget;
console.log( "respHandler:n", request.response );
break;
case egret.IOErrorEvent.IO_ERROR:
console.log( "respHandler io error" );
break;
}
}
var progressHandler = function( evt:egret.ProgressEvent ):void{
console.log( "progress:", evt.bytesLoaded, evt.bytesTotal );
}
request.once( egret.Event.COMPLETE, respHandler, null);
request.once( egret.IOErrorEvent.IO_ERROR, respHandler, null);
request.once( egret.ProgressEvent.PROGRESS, progressHandler, null);
request.open( url, egret.HttpMethod.GET );
request.send( );
HttpRequest 默认的加载类型是 TEXT ,因此不需要专门设定。
需要侦听的主要事件是 COMPLETE ,从这里获取数据。
要考虑意外的情况,在 IO_ERROR 做这些情况的处理。
加载进度事件是 ProgressEvent.PROGRESS , 在加载内容较大的资源时比较有用。
加载二进制
var url = "resource/assets/egret_icon.png";
var request:egret.HttpRequest = new egret.HttpRequest();
request.responseType = egret.HttpResponseType.ARRAY_BUFFER;
var respHandler = function( evt:egret.Event ):void {
switch ( evt.type ){
case egret.Event.COMPLETE:
var request:egret.HttpRequest = evt.currentTarget;
var ab:ArrayBuffer = request.response;
console.log( "respHandler:n", ab.byteLength );
break;
case egret.IOErrorEvent.IO_ERROR:
console.log( "respHandler io error" );
break;
}
}
request.once( egret.Event.COMPLETE, respHandler, null);
request.once( egret.IOErrorEvent.IO_ERROR, respHandler, null);
request.open( url, egret.HttpMethod.GET );
request.send( );
加载二进制数据,先设置 HttpRequest 的加载类型为 ARRAY_BUFFER。
数据加载完成后可从 response 属性取到 ArrayBuffer 对象,即可进行进一步读取操作。