2016-12-30 49 views
1

我试图通过远程API通过ajax在android中发送创建的照片。我正在使用Camera Picture Background插件。FormData中的Blob为空

照片创建正确,我通过ajax GET请求获取并将其编码为base64格式。在调试工具中,我可以通过GET请求日志查看图像本身。

接下来,我分析它的base64成团块,并尝试将其附加到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}

Btw。如果我之前尝试console.log我的blobObj,我看到它是 blob,它的大小,类型属性和分片方法 - 为什么在追加到FormData之后变为null?

编辑:

console.log(blobObj);给出:

Blob {type: "image/jpeg", size: 50778, slice: function}

EDIT2 - 一步一步CODE:

我有网址到本地的形象,让我们假设它存储在imagePath变量。

首先,我得到这个文件,并将其解析为base64:

function base64Encode(){ 
    var CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz/"; 
    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); 
    }). [...] 
}); 
+1

制作blob像这样'var blob = new Blob([payLoad],{type:'image/png'});' – Viney

+0

我这次得到一个错误:'您上传的文件不是图像或损坏的图像 – mrmnmly

+1

你是如何将这个base64-image转换成blob的?我使用filereader及其readAsArrayBuffer方法作为blob构造函数的第一个参数。和使用文件名可能会帮助像[这里](http://stackoverflow.com/questions/6664967/how-to-give-a-blob-uploaded-as-formdata-a-file-name) – Blauharley

回答

1

我最近没有这样做,但这个工程我。我希望它也能和您:

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); 
    } 
    }) 
}); 

引用既修饰功能base64ToBlobgetBase64ImageByURL

+0

让我知道它是否也与你合作。 – Blauharley

+0

你好,我已经改变了代码使用画布,但仍然,当发送时,formData'文件(在我的情况下 - '照片')仍然是'空'! :/ btw。我没有访问服务器代码的权限。 – mrmnmly

+0

使用画布可以在上传之前裁剪图像,但是当您需要整个图像时,我更喜欢filereader或XMLHttpRequest对象。我附加了一个使用XMLHttpRequest对象的较短变体。我用铬/ FF和边缘测试了这个。请更新您的代码。 – Blauharley