as3中的string类采用的是unicode的UTF-16编码。
as3默认传递数据到服务器以及接受服务器数据都采用utf-8编码。
1.传递数据到服务器
如果服务器request接受的是gbk编码,则需要将string转换为gbk传递到服务器。有两种解决方法:
A、如果如果本身就是中文操作系统,可以usecodepage=true,这时候中文参数将转换为gbk编码传递
B、借助bytearray进行转码。我们可以采用bytearray的writemutibytes方法,将unicode的string按照需要的编码方式存放到bytearray中。然后一个byte一个byte的读并转换为16进制。代码如下:
var src:String = "中文";
var des:String = "";
var tmpbytearr:ByteArray = new ByteArray();
tmpbytearr.writeMultiByte(src, "GBK");//参看注解四
tmpbytearr.position = 0;//重要!!!参看注解1
for (var j=0; j<tmpbytearr.length; j++)
{
des += tmpbytearr.readUnsignedByte().toString(16);
}
trace(des);//d6d0cec4
2.从服务器接受数据
如果接受回来的是gbk编码(如一个html页,或者mp3的id3阿等),则需要转换为unicode编码方可正确显示。
同样有两种方法:
A、如果load前codepage就已经为true
服务器返回了一串编码---flash接受编码---查找codepage映射将这些编码转换为unicode编码,得到正确的string,能正确显示
B、如果codepage为false
服务器返回了一串编码---flash接受编码---flash以为是utf-8编码,按照某种算法将这些utf-8编码转换为utf-16编码存放在string中,显示错误
错误的原因是因为,传回来的编码被错误的按照utf-8编码转换为utf-16编码,于是trace的时候,查找到的字符完全是错误的,这时可以借助bytearray进行转码。
首先根据bytearray的writeutfbytes方法,将接受的编码完整的放到bytearray中,然后按照正确的编码方式readmutibytes。代码如下:
经测试,上述代码不能正确的工作,原因是在将不是utf-8编码的字节流按照utf-8转换为utf-16的算法,导致信息丢失或者说错乱,导致后台的utf-16字串writeMultiByte逆转换回来时无法完全恢复到接收到的原始字节流。一、
var src:String = String.fromCharCode(0xd6d0, 0xcec4);//“中文”的gbk编码
var des:String = "";
var tmpbytearr:ByteArray = new ByteArray();
tmpbytearr.writeMultiByte(src, "unicode");//
tmpbytearr.position = 0;//重要!!!参看注解1
des = tmpbytearr.readMutiByte(tmpbytearr.length, "GBK");
trace(des);
二、
var src:String = loader.data;
var des:String = "";
var tmpbytearr:ByteArray = new ByteArray();
tmpbytearr.writeMultiByte(src, "utf-8");//或者writeutfbytes
tmpbytearr.position = 0;//重要!!!参看注解1
des = tmpbytearr.readMutiByte(tmpbytearr.length, "GBK");
trace(des);
另外,一失效的原因是writeMultiByte(src, "unicode")好像有bug,奇怪的tarmina的源文件唯独没有read和writemultibyte方法!
C、可以采用另一种解决方案,将loader接受的数据设定为二进制,这样可以直接把loader的data当作bytearray,代码如下
var tmpbytearr:ByteArray = ByteArray(loader.data);
tmpbytearr.position = 0;
des = tmpbytearr.readMutiByte(tmpbytearr.length, "GBK");
trace(des);
注解一:bytearray的read和write都是从position处开始,而read会导致position变到读取结束处,write也会导致position变到写入结束处,如果在read或者write操作后注意position的归位,运行将出现Error #2030!
注解二:writeMultiByte(src, "utf-8")等价于writeUTFBytes
注解三:bytearray的tostring方法,如果usecodepage是true,会按照codepage解码bytearray;否则按照utf-8解码输出
注解四:writeMultiByte(src, charset)的过程,循环对src中的每一个字符进行如下动作,对每一个字符的unicode编码查找charset的codepage,得到charset对应的该字符编码!所以如果某个字符的在charset字符集中不存在,转换得到的是3f,也就是一个问号!