1

This is a very specific problem, and I am yet to find anyone else asking it.

Basically I have a servlet that accepts some parameters and returns a PNG image. I know the servlet works because if I open the page itself with the given parameters, the file is created and downloaded successfully. I need some way of taking this generated PNG and load it into an HTML5 Canvas.

I do NOT have access to changing the servlet and it has to be a POST request as it was not designed by me. My code is essentially just a jQuery post request at this point but here it is:

$.post("../dgexport?format=png",
{
    data: localStorage.getItem("dg::export"),
    responseType: "blob",
},
function(res){
    loadCanvas(res);
});

function loadCanvas(image) {
    var canvas = document.getElementById('myCanvas');
    var context = canvas.getContext('2d');

    // load image
    context.drawImage(image, 0, 0); 
}

When I open up the console and look at the data response of the POST request it looks like in the console:

�PNG↵↵IHDR��lD�V    pHYs�� IDATx��~---���088'���� IDAT��?��q%�

(this is not the whole thing but I'm hoping it's enough to give a hint to anyone willing to help)

Any help would be greatly appreciated! I've tried a lot of different methods and I'm really stumped on this one.

user3084366
  • 1,103
  • 2
  • 9
  • 12
  • A blob is binary data, but it looks like you're accessing the response as a _String_. How are you invoking `loadCanvas`? – Paul S. Mar 06 '15 at 18:12
  • Just on load of the post request. I was trying to access the data type as "blob" because before I was attempting to encode the image as a URI component and load it that way.. but I've tried specifying it as "image/png" as well. I think I'm conceptually missing something important here – user3084366 Mar 06 '15 at 18:19
  • Show us the code around your invocation of `loadCanvas` – Paul S. Mar 06 '15 at 18:20
  • It's in what I posted up there in the response function to the request. When I run it as is the error I get in the console is 'Uncaught TypeError: Failed to execute 'drawImage' on 'CanvasRenderingContext2D': No function was found that matched the signature provided.' – user3084366 Mar 06 '15 at 18:23

2 Answers2

2

You cannot do typed requests with jQuery ajax see here
Also you're have to pass an image element to context.drawImage not a blob or string.

Making a post request to get an image seems like bad design to be but can be done with raw XMLHttpRequest.

var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
    if (this.readyState == 4 && this.status == 200){
        var img = document.getElementById('img');
        var url = window.URL || window.webkitURL;
        img.onload = function(){
            loadCanvas(this);
        }
        img.src = url.createObjectURL(this.response);
    }
}
xhr.open('POST', "../dgexport?format=png");
xhr.responseType = 'blob';
xhr.send($.param({data: localStorage.getItem("dg::export")}));      
Community
  • 1
  • 1
Musa
  • 96,336
  • 17
  • 118
  • 137
  • Thank you so much! This worked. I agree it's bad design but I have no control over that aspect of this project. Thanks for a workable solution. – user3084366 Mar 06 '15 at 18:52
-1

Looks like the res being passed into your success function isn't coming back as the expected Blob, which means you may need to convert it into one

function (res) {
    if (res instanceof Blob) // function invoked as expected
        return loadCanvas(res);
    if (typeof res === 'string') // function invoked with String
        return loadCanvas(new Blob([res], {type: 'image/png'});
    console.warn('Unexpected Response:', res); // anything else
}
Paul S.
  • 64,864
  • 9
  • 122
  • 138