1

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?

Andrew Simpson
  • 6,883
  • 11
  • 79
  • 179

1 Answers1

2

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.

Community
  • 1
  • 1
Patrick Hofman
  • 153,850
  • 22
  • 249
  • 325
  • hi, thanks for taking the time to look at this. I got that code from a previous StackOverFlow question http://stackoverflow.com/questions/5366727/convert-array-of-byte-values-to-base64-encoded-string-and-break-long-lines-java – Andrew Simpson Feb 11 '14 at 11:06
  • I have not got a clue what I should be using instead of null though – Andrew Simpson Feb 11 '14 at 11:07
  • I admit I may not be thinking clearly here. I have changed to this: live1x4.src = 'data:image/bmp;base64,' + encode(response); function encode(d) { return String.fromCharCode.apply(d); } I assume this is not what you meant? How should I code it pls? – Andrew Simpson Feb 11 '14 at 11:26
  • 1
    You have to keep the `return btoa` line, but change the line above it. – Patrick Hofman Feb 11 '14 at 11:39
  • Hi, I have changed it to this: function encode(d) { var str = String.fromCharCode.apply(d); return btoa(str).replace(/.{76}(?=.)/g, '$&\n'); } I do not get an image though. When I inspect the element via Chrome I get this : I may need to think of different approach. Thank you so much for your time – Andrew Simpson Feb 11 '14 at 11:48
  • I have been trying and trying to get this working, but I have no clue at the moment. – Patrick Hofman Feb 11 '14 at 12:28
  • Another small comment: you use `data:image/bmp` while the type returned from the service is `image/jpg`. – Patrick Hofman Feb 11 '14 at 12:31
  • Hi, yes I have tried changing bmp to jpeg but it did not make a difference unfortuntaley – Andrew Simpson Feb 11 '14 at 12:35
  • @AndrewSimpson: I know, just to avoid problems later on. – Patrick Hofman Feb 11 '14 at 12:35