Sunday, 16 April 2017

Why C# side pass 1.3M bytes/string to js. js recieve 2.0M bytes but only 1.3M string?

today I meet a weird issue....

I don't know why I recieve 2M bytes and transfer to 1.3M string. And in C# side,I checked I only send 1.3M string data.

I pass a string from C# MVC to js ajax response.
in C# side, it encoding with UTF16.
I change it to bytes so that I can check it byte size. It show 1.3M bytes.

In js side, responseType = arraybuffer.
And the arraybuffer length = 2016806.

I change arraybuffer to uint8Array(show length=2016806) then transform to js string string length = 689060(680K chars)
then I use sizeof function(custom function)to check the byte size.
it show the 1.3M......
What's happen in this process?.

I sincerely appreciate for your reply!

Js Side:

xhr.responseType="arraybuffer"
xhr.send(JSON.stringify({ sessionId: sessionId, pageId: pageId }));
xhr.addEventListener("load", function (ev) {
    var arrayBuffer = xhr.response;
    var byteArray = new Uint8Array(arrayBuffer);
    var reText = Utf8ArrayToStr(byteArray);
    var size = sizeof(reText,"utf-16");

In Chrome Dev Tool Watch

reText.length:689060
byteArray.length:2016806
size:1378120
byteArray=Uint8Array(2016806)
arrayBuffer.byteLength:2016806

C# side:

        [HttpPost]
        public string GetReplayData(string sessionId, string pageId)
        {
            var parameters = JsonConvert.SerializeObject(new { sessionId, pageId });
            var result = _provider.Get(parameters);
            return JsonConvert.SerializeObject(result);
        }

C# in VS watch

Encoding.Unicode.GetBytes(JsonConvert.SerializeObject(result)).Length   1378120 
JsonConvert.SerializeObject(result[0].RawData).Length   688875  

JS sizeof function:

var sizeof = function(str, charset){
        var total = 0,
            charCode,
            i,
            len;
        charset = charset ? charset.toLowerCase() : '';
        if(charset === 'utf-16' || charset === 'utf16'){
            for(i = 0, len = str.length; i < len; i++){
                charCode = str.charCodeAt(i);
                if(charCode <= 0xffff){
                    total += 2;
                }else{
                    total += 4;
                }
            }
        }else{
            for(i = 0, len = str.length; i < len; i++){
                charCode = str.charCodeAt(i);
                if(charCode <= 0x007f) {
                    total += 1;
                }else if(charCode <= 0x07ff){
                    total += 2;
                }else if(charCode <= 0xffff){
                    total += 3;
                }else{
                    total += 4;
                }
            }
        }
        return total;
    }

JS UTF8ArrayToStr:

function Utf8ArrayToStr(array) {
    var out, i, len, c;
    var char2, char3;

    out = "";
    len = array.length;
    i = 0;
    while(i < len) {
    c = array[i++];
    switch(c >> 4)
    { 
      case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
        // 0xxxxxxx
        out += String.fromCharCode(c);
        break;
      case 12: case 13:
        // 110x xxxx   10xx xxxx
        char2 = array[i++];
        out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F));
        break;
      case 14:
        // 1110 xxxx  10xx xxxx  10xx xxxx
        char2 = array[i++];
        char3 = array[i++];
        out += String.fromCharCode(((c & 0x0F) << 12) |
                       ((char2 & 0x3F) << 6) |
                       ((char3 & 0x3F) << 0));
        break;
    }
    }

    return out;
}



via guofu

No comments:

Post a Comment