Kode
Kode

Reputation: 3215

Convert and upload canvas as image

I need to upload a canvas (saved as a png image) via jQuery Ajax. If I upload an image via a multipart form, where the user browses to a file than hits a submit button it works, but I need to capture a canvas and upload the image where the user is not uploading a file, but rather hitting a button to have the canvas converted than uploaded.

Here is an example form submit that uploads a file once a user browses and uploads their file:

<form action="http://myrestservice/endpoint" name="form" id="formId" method="post" enctype="multipart/form-data">
<input type="file" name="File1" size="50" maxlength="50" /><a class="textLabel">*** Upload a file is required</a>
<input type="submit" value="Submit Request">
</form>

This is only to demonstrate that the Web Service works. It states that the type of transfer is Document. I also get a 200 OK response.

If I create a different page with a canvas and add a button to upload the canvas to an image, it states that the type of transfer is xhr. I also get a 200 OK response.

Here is my JavaScript for uploading a canvas once it's converted to an image. What is interesting is that this code gives me a "not found in Access-Control-Allow-Origin header." error, while the regular manual upload does not:

$scope.imageMe = function () {
    var canvasImage = document.getElementById("c");
    var img = canvasImage.toDataURL("image/png");
    var filename = 'Test.png';
    var formdata = new FormData();
    formdata.append(filename, img);

    $.ajax({
        url: 'http://myrestservice/endpoint',
        type: "POST",
        data: formdata,
        processData: false,
        contentType: false,
        success: function (result) {
            console.log("Upload complete!");
        },
        error: function (error) {
            console.log("Something went wrong!");
        }            
    });
}

UPDATE:

I am able to post, but I don't get a response, as I get a cross origin error. The application vendor has replied with:

The page where you want to use the Ajax call, needs to send a correct access-control-allow-origin header. (this needs to be done by the webserver)

How/where do I add this in the AJAX to allow a cross origin call since the Web Service is in another domain?

UPDATE 2:

The vendor has responded with the following requirements. Given this, how do I code my AJAX request to work?

The HTTP POST requests must meet the following requirements:

Upvotes: 1

Views: 4309

Answers (2)

Kaiido
Kaiido

Reputation: 136618

If you need to upload this as a file, e.g accessible in php by $_FILES['your_file'], you need to first convert it to a blob.

Unfortunately, canvas element's toBlob method is only implemented in Firefox, so I had to tweak this great answer. (You can use it if you need to convert to jpeg).

$scope.imageMe = function () {

     var send= function(blob){
        var filename = 'Test.png';
        var formdata = new FormData();
        formdata.append('your_file', blob, filename);

        $.ajax({
           url: 'http://myrestservice/endpoint',
           type: "POST",
           data: formdata,
           processData: false,
           contentType: false,
           success: function (result) {
              console.log("Upload complete!");
           },
           error: function (error) {
              console.log("Something went wrong!");
           }
        })            
    }

    var canvasImage = document.getElementById("c");
    if(!canvasImage.toBlob){
       var dataURL = canvasImage.toDataURL();
       var bytes = atob(dataURL.split(',')[1])
       var arr = new Uint8Array(bytes.length);
       for(var i=0; i<bytes.length; i++){
          arr[i]=bytes.charCodeAt(i);
       }
       send(new Blob([arr], {type:'image/png'}));
    }
    else
       canvasImage.toBlob(send);
}

Now as to why you've got this "Access-Control-Allow-Origin" error, @Yotam Omer gave you a good answer.

Upvotes: 3

Yotam Omer
Yotam Omer

Reputation: 15356

The Access-Control-Allow-Origin header error means your service doesn't allow cross-domain requests.

You can change this header like so (php):

 header("Access-Control-Allow-Origin: *");

Note that this will allow requests from any domain, for security reasons I would recommend replacing the * with the domain name you want to make requests from.

Upvotes: 2

Related Questions