我正在尝试通过远程 API 通过 ajax 在 android 中发送创建的照片。我正在使用 Camera Picture Background 插件。
照片已正确创建,我通过 ajax GET
请求获取它并将其编码为 base64 格式。在调试工具中,我可以通过 GET
请求日志查看图像本身。
接下来我将它的 base64 解析为 Blob 并尝试将它附加到 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}
。
顺便说一句。如果我尝试 console.log
我的 blobObj
,我看到 它是 一个 blob,有它的大小、类型属性和切片方法 - 为什么它在附加到 FormData
后变为空值?
编辑:
console.log(blobObj);
给出:
Blob {type: "image/jpeg", size: 50778, slice: function}
EDIT2 - 分步代码:
我有本 map 片的 url,我们假设它存储在 imagePath
变量中。
首先,我得到这个文件并将其解析为 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);
}). [...]
});
最佳答案
我最近没有这样做,但这对我有用。我希望它也适用于您:
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):
<?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 成功将上传的图像移动到该目录之前,可能需要修改目录的一些读/写权限。
getBase64ImageByURL 函数已经可以返回一个 blob 对象,但通过返回一个 base64 图像,您可以在上传之前在 html-image-tag 中向用户显示该图像。
如果不需要向用户显示该图像,那么您还可以缩短所有步骤:
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
关于javascript - FormData 中的 Blob 为空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41398692/