从画布发送图像,并等待AJAX POST响应



我将通过ajax将画布的内容发送到我的API端点,我希望能够等待响应的到来,然后再继续执行下一个函数。我的发送功能如下:

function sendPicture(){
var video = document.getElementById('video');
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
if (width && height) {
canvas.width = width;
canvas.height = height;
context.drawImage(video, 0, 0, width, height);
var fd = new FormData();
fd.append('video', null);
var reso;
canvas.toBlob(function(blob){
fd.set('video', blob);
}, 'image/jpeg');
reso = $.ajax({
url: "/img",
type : "POST",
processData: false,
contentType: false,
data : fd,
dataType: "text",
});
return reso;
}
}

当在toBlob回调中使用ajax语句时,该函数已经在工作,但在这样做时,我再也无法访问主作用域来阻止ajax承诺。从函数的当前版本来看,我认为如果我设法在回调范围之外提取blob参数就足够了,尽管我本以为fd.set('video', blob)语句已经从最初创建它的范围之外设置了formData对象。

有人有更好的建议吗?如果没有带回调的方法,我如何将画布转换为blob?或者更好的是,我如何填写外围范围的表格数据?

不清楚如何获得width&高度,但它可以这样工作,只需在回调之外创建一个函数,并在回调内部调用它,这样你就可以从之外的回调内部访问数据

function sendPicture(){
var video = document.getElementById('video');
var canvas = document.getElementById('canvas');

var context = canvas.getContext('2d');
if (width && height) {
canvas.width = width;
canvas.height = height;
context.drawImage(video, 0, 0, width, height);


}
var fd = new FormData();
fd.append('video', null);

var setBlobOutside = function (blob){
fd.set('video', blob);
}
var reso;
canvas.toBlob(function(blob){
setBlobOutside(blob);
}, 'image/jpeg');

reso = $.ajax({
url: "/img",
type : "POST",
processData: false,
contentType: false,
data : fd,
dataType: "text",
});

return reso;
}
}

您的var fd = new FormData();没有接收到任何数据,也没有向其附加数据,因此它是空的。。你可以这样做fd.append('key1', 'value1');,也可以这样做,new FormData([data]);

下面是一个关于如何使用文件异步发送表单数据的示例

<form id="formElem">
<input type="text" name="firstName" value="John">
Picture: <input type="file" name="picture" accept="image/*">
<input type="submit">
</form>
<script>
formElem.onsubmit = async (e) => {
e.preventDefault();
let response = await fetch('/article/formdata/post/user-avatar', {
method: 'POST',
body: new FormData(formElem)
});
let result = await response.json();
alert(result.message);
};
</script>

最后,我使用了一个promise构造函数,其灵感来自画布外的访问blob值。ToBlob((异步函数。在以下我实现的解决方案中:

function sendPicture(width, height){
var video = document.getElementById('video');
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
canvas.width = width;
canvas.height = height;
context.drawImage(video, 0, 0, width, height);
return new Promise(function(resolve, reject) {
canvas.toBlob(function(blob) {
var fd = new FormData();
fd.set('video', blob);
$.ajax({
url: "/img",
type : "POST",
processData: false,
contentType: false,
data : fd,
dataType: "text",
})
.done(function(respPost) {
resolve(respPost)
})
.fail(function(data) {
console.log(data);
});
})
})
}

然后在html代码中调用:

<script>
$(function() {
var htmltakebutton = document.getElementById("takebutton");
htmltakebutton.addEventListener('click', function(ev){
var promiseSendPicture = sendPicture(250, 250);
promiseSendPicture
.then(function(respPost){
console.log(respPost);
updateTakenPhoto();
});
ev.preventDefault();
}, false);
})()
</script>

最新更新