【发布时间】:2015-12-12 07:16:39
【问题描述】:
正如标题所暗示的,这是一个有趣的用例。我有一个可以转换为图像的 HTML5 画布。我使用 AngularJS 作为前端,在我的网站后端使用 Node/Express。将 HTML5 画布转换为图像按预期工作,我可以使用 jQuery AJAX(不使用 Node/Express)将其上传到单独的 Web 服务,如下所示:
$scope.webService = function () {
var send = function (blob) {
var filename = 'Test.pdf';
var formdata = new FormData();
formdata.append('File1', blob, filename);
$.ajax({
url: 'http://awebservice.net/endpoint',
type: "POST",
data: formdata,
mimeType: "multipart/form-data",
processData: false,
contentType: false,
crossDomain: true,
success: function (result) {
console.log("Upload complete!");
},
error: function (error) {
console.log("Something went wrong!");
}
})
}
var canvasImage = document.getElementById("c");
if (!canvasImage.toBlob) {
var dataURL = canvasImage.toDataURL();
var bytes = atob(dataURL.split(',')[1])
var arr = new Uint8Array(bytes.length);
for (var i = 0; i < bytes.length; i++) {
arr[i] = bytes.charCodeAt(i);
}
send(new Blob([arr], { type: 'image/png' }));
}
else
canvasImage.toBlob(send);
}
我在另一个场景中使用 Node/Express,如果我使用带有提交按钮的标准输入表单,我可以通过 Node 将图像上传到 Azure。这是用户通过文件输入和提交按钮手动上传的图像上传到 Azure Blob 存储的 Node/Express 代码,其中 /upload 在 HTML5 表单的表单操作上调用:
app.post('/upload4', function (req, res) {
var form = new formidable.IncomingForm();
form.parse(req, function (err, fields, files) {
var options = {
contentType: files.myfile.type,
metadata: { fileName: files.myfile.name }
};
blobSvc.createBlockBlobFromLocalFile('blob5', files.myfile.name, files.myfile.path, options, function (error, result, response) {
if (!error) {
// file uploaded
res.send('file uploaded!');
}
});
});
console.log(req);
});
但是,我需要在“幕后”传递我转换后的 HTML5 Canvas,用户不必通过 Web 表单下载和重新上传 HTML5 Canvas 图像,而是在单击时转换 Canvas,然后图像被上传到 Azure(参见上面的第一个示例,了解使用不使用 Node/Express 的不同 Web 服务的工作示例,该 Web 服务上传通过 jQuery AJAX 转换为图像的 HTML5 画布)。本质上,由于我使用 Node/Express 来管理 Azure Blob 存储,因此我希望上传功能适用于我的 jQuery AJAX 示例。
我设想我可以将图像数据/变量传递回 Node/Express,如下所示:
AngularJS 前端控制器代码(绑定到名为“upload()”的 ng-click 按钮操作):
$scope.upload = function () {
var canvasImage = document.getElementById("c");
var img = canvasImage.toDataURL("image/png");
var filename = 'Texture_0.png';
$http.post('/upload', { filename: filename, file: img }).success(function (data) {
console.log(data);
});
}
Node/Express 后端代码:
app.post('/upload', function (req, res) {
var filename = req.filename;
var file = req.file;
blobSvc.createBlockBlobFromLocalFile('mycontainer', filename, file, function (error, result, response) {
if (!error) {
console.log("Uploaded" + result);
// file uploaded
}
else {
console.log(error);
}
});
});
当我点击“魔术按钮”将 Canvas 转换为图像(图像转换有效)并上传(上传无效)时,出现如下 Node 错误:
错误:函数 createBlockBlobFromFile 的必需参数 blob 是 未定义
我还将“文件名”和“文件”记录到节点控制台并得到“未定义”。
客户端 我在浏览器的控制台中收到 500 内部服务器错误。但是,使用“网络”选项卡,我更深入地研究并看到“请求有效负载”的“文件”base64 编码和“文件名”是正确的。
我很大程度上怀疑我没有正确地将变量传递给 Node/Express,这就是导致 Azure 调用失败的原因。我还想知道由于通过输入表单上传图像是否适用于 Azure/Node,我是否应该以某种方式将转换后的 Canvas 作为 formdata 传递,但不确定如何实现/应该尝试它。
我的问题是,如何传递正确的变量/数据,以便我的画布可以从 AngularJS 前端上传到 Azure Blob 存储到 Node/Express 后端?
【问题讨论】: