2013-07-15 16 views
44

Niedawno poprosił innego (pokrewne) pytanie, które prowadzą do tego follow up pytania: Submitting data instead of a file for an input formStosując metody ajax jQuery do pobierania obrazów jako blob

Czytanie przez jQuery.ajax() dokumentacji (http://api.jquery.com/jQuery.ajax/), to wygląda na to, że lista akceptowanych typów danych nie zawiera obrazów.

Próbuję pobrać obraz przy użyciu jQuery.get (lub jQuery.ajax, jeśli muszę), zapisać ten obraz w Blob i przesłać go na inny serwer w żądaniu POST. Obecnie wygląda na to, że z powodu niezgodności typów danych moje obrazy są uszkodzone (rozmiar w niedopasowaniu bajtów itp.).

Kod wykonać to w następujący sposób (to jest w coffeescript ale nie powinno być trudne do analizowania):

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) 

Jak mogę odzyskać ten obraz jako blob zamiast?

+0

Myślę, że trzeba zmienić typ odpowiedzi po stronie serwera. –

+0

Próbuję pobrać obraz z dowolnego adresu URL, a nie z serwera, który jest moim właścicielem. – jabalsad

+0

Spójrz na to http://stackoverflow.com/questions/4285042/can-jquery-ajax-load-image –

Odpowiedz

73

Nie można tego zrobić z jQuery ajax, ale z natywnym 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();  

EDIT

Więc ponowne ten temat, wydaje się, że rzeczywiście jest to możliwe, aby to zrobić z jQuery 3

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%>

lub

użytku xhrFields do ustawienia responseType

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%>

+0

Dzięki. Właśnie to rozgryzłem i zobaczyłem twoją odpowiedź. Jest podobny do mojego (oprócz faktu, że umieszczam go w formularzu, zamiast ustawiać go na obiekcie ).I tak oznaczysz to jako poprawną :) – jabalsad

+0

@jabalsad pytanie z pytaniem "Jak mogę pobrać ten obraz jako blob zamiast?", Tak czy inaczej to było tylko po to, aby go zobaczyć, 'handler' zajmie' this.response' i doda do obiektu formdata i wysłać go przez ajax. – Musa

+2

+1, działa świetnie! I FYI, to może wreszcie zostać dodane do jQuery wkrótce: https://github.com/jquery/jquery/pull/1525 – jpatokal

2

Wielkie dziękuję @Musa i tutaj jest schludny funkcja, która przetwarza dane na ciąg base64. Może się to przydać podczas pracy z plikiem binarnym (pdf, png, jpeg, docx, ...) w WebView, który pobiera plik binarny, ale musisz bezpiecznie przenieść dane pliku do swojej aplikacji.

// 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); 
} 
Powiązane problemy