FormData中的Blob为空 [英] Blob in FormData is null
问题描述
我正在尝试通过远程API通过ajax在android中发送创建的照片.我正在使用相机图片背景插件.
I'm trying to send created photo in android via ajax via remote API. I'm using Camera Picture Background plugin.
照片创建正确,我通过ajax GET
请求将其获取,并将其编码为base64格式.在调试工具中,我可以通过GET
请求日志查看映像本身.
Photo is created properly, I'm getting it via ajax GET
request and encode it to base64 format. In debugging tool I can see image itself through GET
request log.
接下来,我将其解析为Blob并尝试将其附加到FormData
:
Next I parse it base64 to Blob and try to attach it to FormData
:
var fd = new FormData();
fd.append('photo', blobObj);
$.ajax({
type: 'POST',
url: 'myUrl',
data: fd,
processData: false,
contentType: false
}).done(function(resp){
console.log(resp);
}). [...]
但是当我发送FormData
时,我在调试器中看到请求中的FormData
等于:{photo: null}
.
But when I send the FormData
I see in debugger that FormData
in request equals to: {photo: null}
.
顺便说一句.如果我较早尝试console.log
我的blobObj
,我会看到这是一个斑点,其大小,类型属性和slice方法-为什么在追加到FormData
后变成空值?
Btw. if I try to console.log
my blobObj
earlier, I see it is a blob, with its size, type properties and slice method - why it becomes a null after appending to FormData
?
console.log(blobObj);
给出:
Blob {type: "image/jpeg", size: 50778, slice: function}
EDIT2-分步代码:
EDIT2 - STEP BY STEP CODE:
我有本地图像的url,我们假设它存储在imagePath
变量中.
I have url to local image, let's assume it is stored in imagePath
variable.
首先,我得到此文件并将其解析为base64:
First, I get this file and parse it to base64:
function base64Encode(){
var CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
var out = "", i = 0, len = str.length, c1, c2, c3;
while (i < len) {
c1 = str.charCodeAt(i++) & 0xff;
if (i == len) {
out += CHARS.charAt(c1 >> 2);
out += CHARS.charAt((c1 & 0x3) << 4);
out += "==";
break;
}
c2 = str.charCodeAt(i++);
if (i == len) {
out += CHARS.charAt(c1 >> 2);
RS.charAt(((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4));
out += CHARS.charAt((c2 & 0xF) << 2);
out += "=";
break;
}
c3 = str.charCodeAt(i++);
out += CHARS.charAt(c1 >> 2);
out += CHARS.charAt(((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4));
out += CHARS.charAt(((c2 & 0xF) << 2) | ((c3 & 0xC0) >> 6));
out += CHARS.charAt(c3 & 0x3F);
}
return out;
}
function getFile(fileData){
var dfd = new $.Deferred();
$.ajax({
type: 'GET',
url: fileData,
mimeType: "image/jpeg; charset=x-user-defined"
}).done(function(resp){
var file = base64Encode(resp);
dfd.resolve(file);
}).fail(function(err){
console.warn('err', err);
dfd.resolve();
});
return dfd.promise();
};
$.when(getFile(imagePath)).then(function(resp){
var fd = new FormData();
resp = 'data:image/jpeg;base64,' + resp;
var imgBlob = new Blob([resp], {type : 'image/jpeg'});
fd.append('photo', img, 'my_image.jpg');
$.ajax({
type: 'POST',
url: 'myUrlToUploadFiles',
data: fd,
processData: false,
contentType: false
}).done(function(resp){
console.log(resp);
}). [...]
});
推荐答案
我最近还没有做过,但这对我有用.我希望它也对您有用:
I've not done this recently, but this works with me. I hope it also works with you:
function getBase64ImageByURL(url) {
var dfd = new $.Deferred();
var xhr = new XMLHttpRequest();
xhr.responseType = 'blob';
xhr.onload = function() {
var reader = new FileReader();
reader.onloadend = function() {
dfd.resolve(reader.result);
}
reader.readAsDataURL(xhr.response);
};
xhr.open('GET', url);
xhr.send();
return dfd.promise();
}
function base64ToBlob(base64Image,toMimeType) {
var byteCharacters = atob(base64Image.replace('data:'+toMimeType+';base64,',''));
var byteNumbers = new Array(byteCharacters.length);
for (var i = 0; i < byteCharacters.length; i++) {
byteNumbers[i] = byteCharacters.charCodeAt(i);
}
var byteArray = new Uint8Array(byteNumbers);
var blob = new Blob([byteArray], {
type: toMimeType
});
return blob;
}
var imageUrl = "https://upload.wikimedia.org/wikipedia/commons/4/49/Koala_climbing_tree.jpg";
getBase64ImageByURL(imageUrl).then(function(base64Image){
var blob = base64ToBlob(base64Image,'image/jpeg');
var fd = new FormData();
fd.append('file', blob, 'my_image.jpg');
$.ajax({
url: 'http://your_host/uploads/testupload.php',
data: fd,
type: 'POST',
contentType: false,
processData: false,
success:function(res){
console.log(res);
},
error:function(err){
console.log(err);
}
})
});
在服务器端(testupload.php):
On server-side(testupload.php):
<?php
if ( 0 < $_FILES['file']['error'] ) {
echo 'Error: ' . $_FILES['file']['error'] . '<br>';
}
else {
$result = move_uploaded_file($_FILES['file']['tmp_name'], $_SERVER["DOCUMENT_ROOT"].$_SERVER["BASE"].'/uploads/'.'my_image.jpg');
var_dump("image uploaded: ".$result);
}
?>
在 move_uploaded_file 成功将上传的图像移动到该目录之前,可能需要修改目录上的某些读/写权限.
It might be necessary to modify some read/write-permissions on a directory before move_uploaded_file succeeds in moving the uploaded image to this directory.
函数 getBase64ImageByURL 已经可以返回blob对象,但是通过返回base64-image,您可以在上传html-image-tag之前向用户显示该图像.
The function getBase64ImageByURL could already return a blob-object but by returning a base64-image you can show an user this image in a html-image-tag before uploading it for instance.
如果不需要向用户显示该图像,那么您还可以缩短所有步骤:
If there is no need to show an user that image, then you can also shorten all steps:
function getBlobImageByURL(url) {
var dfd = new $.Deferred();
var xhr = new XMLHttpRequest();
xhr.responseType = 'blob';
xhr.onload = function() {
dfd.resolve(xhr.response);
};
xhr.open('GET', url);
xhr.send();
return dfd.promise();
}
getBlobImageByURL(imageUrl).then(function(imageBlob){
var fd = new FormData();
fd.append('file', imageBlob, 'my_image.jpg');
console.log(fd.get('file'));// File-object
$.ajax({
url: 'http://your_host/uploads/testupload.php',
data: fd,
type: 'POST',
contentType: false,
processData: false,
success:function(res){
console.log(res);
},
error:function(err){
console.log(err);
}
})
});
对两个已修改函数的引用 base64ToBlob 和 getBase64ImageByURL
references to both modified functions base64ToBlob and getBase64ImageByURL
这篇关于FormData中的Blob为空的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!