这里描述如何在 client 端使用 javascript 处理通过 ajax 调用返回的压缩数据。服务器端使用java 的DeflaterOutputStream来进行数据的压缩。

最早尝试使用jquery$.ajax方法来做 ajax 调用,但是其返回的数据都是字符串类型的,部分字节被强制转换了,导致这部分数据无法正确的解码。

如果仔细观察,浏览器的开发者模式中Response页面得到的数据格式是正常的,但是在 success: function (data)中数据是不正确的。

接收字节流而不是字符串

所以,如果需要 ajax 能够接收字节流而仅仅是字符串,需要使用 XMLHttpRequest自己来实现,v1和 v2都可以,下面给出的代码使用 v2的特性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function ajaxRequest (data) {
var request = new XMLHttpRequest();
request.open(data.type, data.url, true);
request.responseType = "arraybuffer";
request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
request.onload = function (event) {
if (data.success) {
data.success(request.response);
}
};
request.onerror = function (event) {
if (data.error) {
data.error(request.response);
}
};
request.send(data.data);
}

使用的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var szActionUrl = http_host + path;
var content = "userName=" + userName + "&password=" + password;
ajaxRequest({
url: szActionUrl,
type: "POST",
data: content,
success: function (data) {
console.log("success");
decodeToJson(data);
},
error: function (data) {
console.log("failed");
}
});

解压缩

解压缩使用的是 zlib,在使用前先加入引用:

1
<script language="JavaScript" type="text/javascript" src="zlip/inflate.min.js"></script>

javascript 的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function uintToString(uintArray) {
var encodedString = String.fromCharCode.apply(null, uintArray);
var decodedString = decodeURIComponent(escape(encodedString));
return decodedString;
}
function decodeToJson(data) {
var uintArray = new Uint8Array(data);
var inflate = new Zlib.Inflate(uintArray);
var plainArray = inflate.decompress();
var s = uintToString(plainArray);
console.log(s);
var result = JSON.parse(s);
return result;
}

其中的uintToString是用来把 Uint8Array转换成字符串,decodeURIComponent可以正确的处理 utf-8编码的字符。

Comments