为何客户端接收的byte array体积远超服务端发送的大小?
我从Web服务器向客户端发送byte array,代码如下:
byte[] myByteArray = null; // filling myByteArray return Json(myByteArray, JsonRequestBehavior.AllowGet);
该byte array包含480000字节,约480KB,但在Chrome控制台的Network面板中看到响应大小超过1.5MB。请问原因是什么?我猜测是序列化导致的,若如此,如何不序列化直接发送byte array?比如以文件形式发送?
你猜的完全没错!就是JSON序列化在搞事情~
为啥体积膨胀这么多?
当你用Json()方法直接序列化byte数组时,底层会把每个字节转换成Base64编码字符串,再套上JSON数组的结构(方括号、逗号分隔符这些)。Base64本身会把每3字节转成4个字符,体积直接膨胀约33%;再加上JSON数组的额外结构字符,480KB的原始字节最终就会被撑到1.5MB左右,和你看到的现象完全吻合。
怎么直接发送原始字节?
最直接高效的方式就是跳过JSON序列化,直接把字节流返回给客户端,就像发送文件一样:
方案1:返回原始字节流(推荐)
用File()方法返回FileContentResult,服务器会直接把原始字节发送出去,没有任何编码膨胀:
byte[] myByteArray = GetMyByteArray(); // 这里填充你的字节数组 // 直接返回字节流,MIME类型用application/octet-stream表示二进制数据 return File(myByteArray, "application/octet-stream");
如果想让浏览器直接触发下载(而不是在页面里解析),可以加上文件名参数:
return File(myByteArray, "application/octet-stream", "my-data.bin");
这种方式下,Network面板里看到的响应大小就是原始的480KB左右,还能配合服务器的Gzip压缩进一步减小传输体积(大多数Web框架默认支持,比如ASP.NET可以在配置里开启)。
方案2:如果必须用JSON返回(不推荐)
要是因为业务限制必须用JSON格式返回,那可以手动把byte数组转成Base64字符串再封装,这样比直接序列化byte数组少了JSON数组的结构开销,体积会比原来小一点,但还是有Base64的膨胀:
byte[] myByteArray = GetMyByteArray(); var responseData = new { Data = Convert.ToBase64String(myByteArray) }; return Json(responseData, JsonRequestBehavior.AllowGet);
不过这种方式还是不如直接发字节流高效,所以优先选方案1。
内容的提问来源于stack exchange,提问作者Mehdi Souregi

