首页 > 解决方案 > 将 dataURI 转换为文件以通过 REST 上传不起作用,但正常的文件字段上传工作正常

问题描述

我已经实现了一个在 Django Rest Framework 后端接受单个文件上传(配置文件的图像)的解决方案。这条路线 api/people/id/upload_image。只接受带有图像的参数。并且可以通过 HTTP POST 使用。通过例如文件输入字段上传时。Postman,默认的 Django API 或通过我的 Vue.js 应用程序中的浏览器 fetch() 没有问题。所以看起来只要它是一个默认的表单上传字段,它就可以完成它的工作。

但是在我的前端(vuejs 3)中,我使用的是图像裁剪器。用户可以上传图片并通过 javascript 裁剪器裁剪图片。这对 UI 很重要,因为我需要一个方形图像。裁剪器使用 HTMLCanvasElement.toDataURL() 作为导出格式。

似乎并不那么困难的事情让我困了好几天。我只是找不到以upload_image API后端接受的方式转换和发布裁剪图像的方法。我正在使用 Fetch() 发送此 POST 调用。

我不是 javascript 专家,所以我通过互联网获取知识,并通过多种方式进行了尝试;首先从 dataURI 创建一个 BLOB,然后在将其提供给 dataForm 之前创建一个 File 并将其作为 :body 在 Fetch() 中发送

dataURI 似乎没问题,因为我还直接在 HTML 中替换了裁剪的图像。这看起来完全没问题。API 以“HTTP 200 OK”响应。但旧图像不会被替换。

所以我的假设是发送到 API 的图像有问题,因为通过正常的文件上传一切正常。我应该如何以适当的方式转换这个 dataURI,以便它可以被 API 端点发送和接受。以及 API 调用应该如何:标头、正文..

这是我最后一次尝试转换和发送裁剪后的图像:(dataURIimage 可以)

uploadPhoto(context, dataURIimage) {
        const blob = dataURItoBlob(dataURIimage);
        const resultFile = new File([blob], "picture", {
          type: "image/png"
        });
  
        const formData = new FormData();
        formData.append("image", resultFile); 
  
        const headerToken = "Token" + " " + this.getters.getToken;
        const url =
          "https://workserver-7e6s4.ondigitalocean.app/api/people/" +
          this.getters.getProfiel.id +
          "/upload_image/";
        fetch(url, {
          method: "POST",
          headers: {
            'Content-Type': 'multipart/form-data',
            'Authorization': headerToken,
          },
          body: formData,
        })
          .then(function(response) {
            console.log(response.status)
            if (response.ok) {
              return response.json();
            }
          })
          .then(function(data) {
            console.log(data.image);
          })
          .catch(function(error) {
            alert(error + " " + ":ERROR");
          });
      },



function dataURItoBlob(dataURI) {
    // convert base64 to raw binary data held in a string
    // doesn't handle URLEncoded DataURIs - see SO answer #6850276 for code that does this
    var byteString = atob(dataURI.split(',')[1]);

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

    // write the bytes of the string to an ArrayBuffer
    var ab = new ArrayBuffer(byteString.length);
    var ia = new Uint8Array(ab);
    for (var i = 0; i < byteString.length; i++) {
      ia[i] = byteString.charCodeAt(i);
    }
    return new Blob([ab], { type: mimeString });
  }

马丁·德克尔

标签: javascriptdjangovue.jsrestdata-uri

解决方案


推荐阅读