javascript - 将 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 });
}
马丁·德克尔
解决方案
推荐阅读
- macos - 恶意软件 .DMG 包 - 加密参数
- python - 如何使用正则表达式匹配带有冒号的文本?
- reactjs - 为什么我的新字符串值在 React.js 中未定义?
- vue.js - 计算对象 V 模型在更改后未更新
- javascript - 错误:Route.get() 需要回调函数,但得到了 [object Undefined]:
- spring-boot - Spring Boot 应用程序与 Spring Cloud Sleuth 与 Istio 中的 Jaeger 集成
- haskell - 如何通过浏览器正确减少 GET 请求的服务 API 路径 (:>) 组合树?
- json - JSON 中的字段可以有不同的类型,我可以用 Go 中的单个结构来表示它吗?
- python - 检查是否安装了pip?
- java - 如何在 java.util.Map 中转换 google.protobuf.Struct 字段
?