FormData 中的 Blob 为空
Blob in FormData is null
我正在尝试通过远程 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 - 分步代码:
我有 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 成功将上传的图像移动到此目录之前,可能需要修改目录中的一些 read/write-permissions。
函数 getBase64ImageByURL 已经可以 return 一个 blob 对象,但是通过 return 一个 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 and getBase64ImageByURL
我正在尝试通过远程 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 - 分步代码:
我有 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 成功将上传的图像移动到此目录之前,可能需要修改目录中的一些 read/write-permissions。
函数 getBase64ImageByURL 已经可以 return 一个 blob 对象,但是通过 return 一个 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 and getBase64ImageByURL