Ich habe kürzlich eine andere (verwandte) Frage gestellt, die zu dieser Folgefrage führte: Senden von Daten anstelle einer Datei für ein Eingabeformular
Beim Lesen der Dokumentation zu jQuery.ajax () ( http://api.jquery.com/jQuery.ajax/ ) scheint die Liste der akzeptierten Datentypen keine Bilder zu enthalten.
Ich versuche, ein Bild mit jQuery.get (oder jQuery.ajax, wenn ich muss) abzurufen, dieses Bild in einem Blob zu speichern und es in einer POST-Anfrage auf einen anderen Server hochzuladen. Derzeit sieht es so aus, als ob meine Bilder aufgrund der Nichtübereinstimmung in den Datentypen beschädigt sind (Größe in Byte nicht übereinstimmend usw.).
Der Code, um dies auszuführen, lautet wie folgt (er ist in Coffeescript, sollte aber nicht schwer zu analysieren sein):
handler = (data,status) ->
fd = new FormData
fd.append("file", new Blob([data], { "type" : "image/png" }))
jQuery.ajax {
url: target_url,
data: fd,
processData: false,
contentType: "multipart/form-data",
type: "POST",
complete: (xhr,status) ->
console.log xhr.status
console.log xhr.statusCode
console.log xhr.responseText
}
jQuery.get(image_source_url, null, handler)
Wie kann ich dieses Bild stattdessen als Blob abrufen?
quelle
Antworten:
Sie können dies nicht mit jQuery ajax tun, sondern mit nativem XMLHttpRequest.
var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function(){ if (this.readyState == 4 && this.status == 200){ //this.response is what you're looking for handler(this.response); console.log(this.response, typeof this.response); var img = document.getElementById('img'); var url = window.URL || window.webkitURL; img.src = url.createObjectURL(this.response); } } xhr.open('GET', 'http://jsfiddle.net/img/logo.png'); xhr.responseType = 'blob'; xhr.send();
BEARBEITEN
Wenn Sie dieses Thema noch einmal aufgreifen, scheint es tatsächlich möglich zu sein, dies mit jQuery 3 zu tun
jQuery.ajax({ url:'https://images.unsplash.com/photo-1465101108990-e5eac17cf76d?ixlib=rb-0.3.5&q=85&fm=jpg&crop=entropy&cs=srgb&ixid=eyJhcHBfaWQiOjE0NTg5fQ%3D%3D&s=471ae675a6140db97fea32b55781479e', cache:false, xhr:function(){// Seems like the only way to get access to the xhr object var xhr = new XMLHttpRequest(); xhr.responseType= 'blob' return xhr; }, success: function(data){ var img = document.getElementById('img'); var url = window.URL || window.webkitURL; img.src = url.createObjectURL(data); }, error:function(){ } });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.0.0/jquery.min.js"></script> <img id="img" width=100%>
oder
Verwenden Sie xhrFields, um den responseType festzulegen
jQuery.ajax({ url:'https://images.unsplash.com/photo-1465101108990-e5eac17cf76d?ixlib=rb-0.3.5&q=85&fm=jpg&crop=entropy&cs=srgb&ixid=eyJhcHBfaWQiOjE0NTg5fQ%3D%3D&s=471ae675a6140db97fea32b55781479e', cache:false, xhrFields:{ responseType: 'blob' }, success: function(data){ var img = document.getElementById('img'); var url = window.URL || window.webkitURL; img.src = url.createObjectURL(data); }, error:function(){ } });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.0.0/jquery.min.js"></script> <img id="img" width=100%>
quelle
How can I retrieve this image as a blob instead?
, jedenfalls, die nur zur Demo diente,handler
wird sie nehmenthis.response
und zu einem Formdata-Objekt hinzufügen und über Ajax senden.Wenn Sie Fehlermeldungen mit jQuery.AJAX behandeln müssen, müssen Sie die
xhr
Funktion so ändern , dass sie imresponseType
Fehlerfall nicht geändert wird.Sie müssen das
responseType
" Blob " also nur ändern , wenn es sich um einen erfolgreichen Aufruf handelt:$.ajax({ ... xhr: function() { var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function() { if (xhr.readyState == 2) { if (xhr.status == 200) { xhr.responseType = "blob"; } else { xhr.responseType = "text"; } } }; return xhr; }, ... error: function(xhr, textStatus, errorThrown) { // Here you are able now to access to the property "responseText" // as you have the type set to "text" instead of "blob". console.error(xhr.responseText); }, success: function(data) { console.log(data); // Here is "blob" type } });
Hinweis
Wenn Sie debuggen und einen Haltepunkt an der Stelle direkt nach dem Setzen
xhr.responseType
von " blob " platzieren, können Sie feststellen, dass beim Versuch, den Wert für zuresponseText
erhalten, die folgende Meldung angezeigt wird:quelle
.done()
Methode zu behandeln, und wenn etwas schief ging, sollte die Antwort in der.fail()
Methode als "Text" behandelt werden, da die Antwort sonstresponseText
leer war usw. Dies Lösung hat perfekt für mich funktioniert!Ein großes Dankeschön an @Musa und hier ist eine nette Funktion, die die Daten in eine Base64-Zeichenfolge konvertiert. Dies kann nützlich sein, wenn Sie eine Binärdatei (pdf, png, jpeg, docx, ...) in einer WebView verarbeiten, die die Binärdatei abruft. Sie müssen jedoch die Daten der Datei sicher in Ihre App übertragen.
// runs a get/post on url with post variables, where: // url ... your url // post ... {'key1':'value1', 'key2':'value2', ...} // set to null if you need a GET instead of POST req // done ... function(t) called when request returns function getFile(url, post, done) { var postEnc, method; if (post == null) { postEnc = ''; method = 'GET'; } else { method = 'POST'; postEnc = new FormData(); for(var i in post) postEnc.append(i, post[i]); } var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { var res = this.response; var reader = new window.FileReader(); reader.readAsDataURL(res); reader.onloadend = function() { done(reader.result.split('base64,')[1]); } } } xhr.open(method, url); xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); xhr.send('fname=Henry&lname=Ford'); xhr.responseType = 'blob'; xhr.send(postEnc); }
quelle