我如何 POST canvas 中的数据 javascript?

How can I POST canvas data in javascript?

我使用 javascript 和 FastAPI 构建了一个简单的项目。我想 POST canvas javascript 中的图像数据到服务器(FastAPI)。

但是,我收到 422 无法处理的实体错误

# 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())

这是我的代码。我是 javascript 的新人。所以我不知道如何 post 数据到服务器。 我能怎么做?提前致谢。

UploadFile 期望文件以 multipart/form-data 格式发布到端点 - 即作为常规 POST 添加一些元数据。

由于您正在检索图像数据并将其作为 JSON 正文提交,因此这与预期格式不符。你 also want to use canvas.toDataURL() to convert the content to base64 在尝试通过你的 API 提交它之前避免 JSON.

的任何 UTF-8 问题
const pngData = canvas.toDataURL();

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

要处理此请求,请更改您的视图函数签名以接收 input_data 参数(并使用比 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}

MatsLindh 的方法是正确的,但您可以尝试通过 formdata 上传图像,这样您就不必转换为 base64 然后再转换回图像

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