Question

I have an asp.net page.

Inside this page I have an img control/element.

I am calling an ashx page on my server.

This ashx page accepts a timestamp from the client and compares it to a timestamp stored on the server.

If the timestamps do not match then I return an image which has been converted to a byte array (in C#).

If the timestamps do not match then I return a string value of "-1".

So, this is a cut-down of my ashx page:

public void ProcessRequest (HttpContext context) {
    context.Response.AddHeader("Access-Control-Allow-Origin", "*");
    try
    {
        string clientTS = context.Request.QueryString["clientTS"];

        if (clientTS == serverTS)
        {
            //new version available.  refresh browser
            context.Response.ContentType = "text/json";
            string value = "-1";
            context.Response.Write(value);
        }
        else
        {
            context.Response.ContentType = "image/jpg";
            byte[] data = Shared.GetMobileNextFrame("par1", 0);
            context.Response.BinaryWrite(data);
        }
    }
    catch (Exception ex)
    {
        context.Response.ContentType = "text/json";
        context.Response.Write("ERR");
    }
}

And in my javascript code:

function GetImageStatus() {
    finished = false;
    var val = url + '/Mobile/isNewFrame.ashx?Alias=' + Alias + '&CamIndex=' + camIndex + '&Version=' + version + '&GuidLogOn=' + guidLogOn;
    $.ajax({
        url: val,
        type: 'GET',
        timeout: refreshWaitlimit,
        data: lastTS,
        success: function (response, status, xhr) {
            var ct = xhr.getResponseHeader("content-type");
            if (ct.indexOf('json') > -1) {
                //no update
            }
            else {
                try {
                    live1x4.src = 'data:image/bmp;base64,' + encode(response);
                }
                catch (err) {
                    alert(err);
                }
            }
        },
        error: function (jqXHR, textStatus, errorThrown) {
          //handle error
        }
    });
}

function encode(data) {
    var str = String.fromCharCode.apply(null, data);
    return btoa(str).replace(/.{76}(?=.)/g, '$&\n');
}

But I get an error returned:

TypeError: Function.prototype.apply: Arguments list has wrong type

If I just apply:

live1x4.src = 'data:image/bmp;base64,' + btoa(response);

instead of:

live1x4.src = 'data:image/bmp;base64,' + encode(response);

I get this error:

InvalidCharacterError: btoa failed. the string to be encoded contains characters outside of the Latin1 range.

I have tried using a canvas control with example code i have found on this site. I do not get an error but I also do not get an image.

I know the image is valid because my old code was point the image.src directly to the ashx handler (and i was not comparing timestamps).

I do not want to encode the byte array to base64 string on the server because that would inflate the download data.

I was wondering if I was using the wrong context.Response.ContentType but I could not see what else I could use.

What am i doing wrong?

Was it helpful?

Solution

When looking at the documentation at MDN you should pass 1 or more parameters to fromCharCode. You pass none in this line:

var str = String.fromCharCode.apply(null, data);

The syntax is:

String.fromCharCode(num1, ..., numN)

There is although the apply method as your said in comments, but you use it the wrong way. The first parameter shouldn't be null.

The syntax of that is (from Convert array of byte values to base64 encoded string and break long lines, Javascript (code golf)):

somefunction.apply(thisObj[, argsArray])

Just use

var str = String.fromCharCode.apply(data);

So use the thisObj parameter to pass the data.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top