Home > Software design >  How can I POST canvas data in javascript?
How can I POST canvas data in javascript?

Time:05-19

I built a simple project using javascript and FastAPI. I would like to POST canvas image data in javascript to the server(FastAPI).

But, I get the 422 Unprocessable Entity error

# FastAPI
@app.post("/post")
async def upload_files(input_data: UploadFile  = File(...)):
     return JSONResponse(status_code = 200, content={'result' : 'success'})
// javascript
let canvas = document.getElementById("canvas");
let ctx = canvas.getContext("2d");

imageData = ctx.getImageData(0, 0, 112, 112);
fetch("http://{IP}/post", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      input_data: imageData,
    }),
  })
    .then((response) => response.json())

here is my code. I am new one in javascript. so I don't know how can post data to server. How can I do? Thanks in advance.

CodePudding user response:

MatsLindh's way is correct but you can try upload image by formdata so you haven't convert to base64 then convert back to image

const dataURItoBlob = function(dataURI : string) {
    // convert base64/URLEncoded data component to raw binary data held in a string
    var byteString : string;
    if (dataURI.split(',')[0].indexOf('base64') >= 0)
        byteString = atob(dataURI.split(',')[1]);
    else
        byteString = unescape(dataURI.split(',')[1]);

    // separate out the mime component
    var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];

    // write the bytes of the string to a typed array
    var ia = new Uint8Array(byteString.length);
    for (var i = 0; i < byteString.length; i  ) {
        ia[i] = byteString.charCodeAt(i);
    }

    return new Blob([ia], {type:mimeString});
}
const url = canvas.toDataURL()
const file = dataURItoBlob(url)

//add file to formdata

const form = new FormData()
form.append('file', item.file)
//post this form in body

CodePudding user response:

UploadFile expects a file being posted to the endpoint in the multipart/form-data format - i.e. as a regular POST with a bit of added metadata.

Since you're retrieving the image data and submitting it as JSON body, that won't match the expected format. You also want to use canvas.toDataURL() to convert the content to base64 before trying to submit it through your API to avoid any UTF-8 issues with JSON.

const pngData = canvas.toDataURL();

// then in your request:
body: JSON.stringify({
  input_data: pngData,
}),

To handle this request change your view function signature to receive an input_data parameter (and use a better endpoint name than post):

@app.post("/images")
async def upload_files(input_data: str = Body(...)):
     # check the expected format (content-type;<base64 content>)
     # .. and decode it with base64.b64decode()
     return {'content': input_data}
  • Related