2016-12-30 5 views
1

Ich versuche, erstelltes Foto in Android über Ajax über Remote-API zu senden. Ich benutze Camera Picture Background Plugin.Blob in FormData ist null

Foto ist richtig erstellt, ich bekomme es über AJAX GET Anfrage und kodieren Sie es zu Base64-Format. Im Debugging-Tool kann ich das Bild selbst durch GET Anfrageprotokoll sehen.

Next ich analysieren es Blob base64 und versuchen, es zu FormData anbringt:

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); 
}). [...] 

Aber wenn ich die FormData ich in Debugger sehen senden, die FormData in Anfrage gleich zu: {photo: null}.

Btw. wenn ich versuche, console.log mein blobObj früher, sehe ich ist es ein Blob, mit seiner Größe, Typ Eigenschaften und Slice-Methode - warum wird es ein Null nach dem Anhängen an FormData?

EDIT:

console.log(blobObj); gibt:

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

EDIT2 - Schritt für Schritt Code:

Ich habe URL zu lokalen Bild, nehmen wir an, es in imagePath Variable gespeichert wird.

Zuerst bekomme ich diese Datei und analysieren es 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

Fabrikat Blob wie dieses 'var blob = neuer Blob ([payLoad], {type: 'image/png'});' – Viney

+0

Ich erhalte dieses Mal einen Fehler: 'Die Datei, die du hochgeladen hast, war entweder keine Bild oder ein beschädigtes Bild? – mrmnmly

+1

Wie haben Sie dieses base64-Bild in einen Blob umgewandelt?Ich verwende den filereader und seine readAsArrayBuffer-Methode als ersten Parameter für den Blob-Konstruktor. Und die Verwendung eines Dateinamens könnte auch helfen wie [hier] (http://stackoverflow.com/questions/6664967/how-to-give-a-blob-uploaded-as-formdata-a-file-name) – Blauharley

Antwort

1

Ich habe das nicht vor kurzem getan, aber das funktioniert bei mir. Ich hoffe, es funktioniert auch mit Ihnen:

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

Auf Server-Seite (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); 
    } 

?> 

Es könnte notwendig sein, einige Lese-/Schreibberechtigungen für ein Verzeichnis vor move_uploaded_file zu ändern gelingt es, das hochgeladene Bild in dieses Verzeichnis zu verschieben.

Die Funktion getBase64ImageByURL konnte bereits ein Blob-Objekt zurück, sondern durch ein Base64-Bild zurückkehren Sie einen Benutzer dieses Bild in einem HTML-Bild-Tag, bevor es zum Beispiel des Hochladen zeigen können.


Wenn es nicht notwendig ist, ein Benutzer das Bild zu zeigen, dann verkürzen Sie können auch alle Schritte:

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

Verweise auf beiden modifizierten Funktionen base64ToBlob und getBase64ImageByURL

+0

lassen Sie mich wissen, ob es auch mit Ihnen gearbeitet hat. – Blauharley

+0

Hallo, Ich habe den Code geändert, um Canvas zu verwenden, aber immer noch, beim Senden, FormData 'Datei' (in meinem Fall -' Foto') ist immer noch 'null'! :/zw. Ich habe keinen Zugriff auf den Servercode. – mrmnmly

+0

Mit Canvas können Sie das Bild vor dem Hochladen zuschneiden, aber wenn Sie das gesamte Bild benötigen, bevorzuge ich filereader oder das XMLHttpRequest-Objekt. Ich habe eine kürzere Variante angehängt, die nur ein XMLHttpRequest-Objekt verwendet. Ich habe das mit Chrome/FF und Edge getestet. Aktualisiere deinen Code bitte. – Blauharley