Download per AJAX & Content Type 'application/force-download'

Wie ich gerade gesehen habe, muss man sich bei jQuery da doch etwas reinlesen, da jQuery nicht von Haus aus Blobs unterstützt oder besser gesagt keinen Filter dafür vordefiniert hat. Folgendes sollte aber gehen:
Javascript:
function loadDocument( element ) {
  $.ajax( 'http://192.168.178.34/file-stream/response.php', {
    'xhrFields' : {
      'responseType' : 'blob'
    },
    'dataType' : 'binary'
  })
  .complete(function ( xhr ) {
    var $a = $( '<a />' ), url = URL.createObjectURL( xhr.response );
    $a.attr({
      'href' : url,
      'download' : 'test.pdf'
    })
    .trigger( 'click' );
    URL.revokeObjectURL( url );
  });
}
 
@einfach nur crack ::

Guten Morgen,

hab das mal eingesetzt, aber irgendwie scheint kommt die gleiche Fehlermeldung.
Code:
jquery.min.js:4 Uncaught InvalidStateError: Failed to read the 'responseText' property from 'XMLHttpRequest': The value is only accessible if the object's 'responseType' is '' or 'text' (was 'blob').

Javascript:
$ = jQuery;
$( document ).ready(function() {
    $('.documentIcon').click(function(){
        var src = $(this).attr('src');
           $.ajax( 'http://192.168.178.34/file-stream/response.php', {
               'xhrFields' : {
                   'responseType' : 'blob'
               },
               'dataType' : 'binary'
        })
        .complete(function ( xhr ) {
            var $a = $( '<a />' ), url = URL.createObjectURL( xhr.response );
            $a.attr({
              'href' : url,
              'download' : 'test.pdf'
            })
            .trigger( 'click' );
            URL.revokeObjectURL( url );
          });
    });
});

Bin bei jQuery noch am Anfang und derzeit wünschte ich ich hätt das mit dem Download gar nicht erst angefangen. Wie auch immer, jetzt muss ich durch... (leider nur wenig Zeit, da ich es Ende der Woche fertig haben muss... )

Aktuell frage ich mich warum responseText ein Fehler sein soll... Die verwende ich doch gar nicht.

LG NetBu||
 
Zuletzt bearbeitet:
Alternativ kannst du ja anstatt mit jquery rumzuknorzen auch einfach deinen alten Code nehmen und die zwei entsprechenden Zeilen vertauschen, es muss nicht immer jQuery sein und man kann auch wenn man jQuery an anderen Orten verwendet mal ein paar Zeilen ohne vollbringen.

Viele Grüsse
Cromon
 
Hallo NetBull

Das kann ich mir kaum vorstellen, funktioniert einwandfrei in Firefox:
public.php


Im Vergleich dazu:
public.php


Viele Grüsse
Cromon
 
@NetBull

Was ist null? requestObject.response? Kann logischerweise nicht testen, ob ich deine Datei herunterladen kann, einerseits wegen CORS, andererseits weil es sich um eine lokale IP handelt.

Viele Grüsse
Cromon
 
Die Sache mit dem .responseText ist, dass es nur verfügbar ist, wenn Du Daten als Zeichenkette erhältst, genauso wie es bei .responseXML für XML-strukturierte Daten ist. Da bei .done( ... ) die Daten für den ersten Parameter laut den definierten Regeln umgewandelt werden, es aber für blob keine derartige Regel gibt, versucht jQuery es als Text zu interpretieren und ruft dann halt die Eigenschaft auf, die es nicht gibt, da die Daten eben keine Zeichenkette sind. Bei .complete( ... ) erhältst Du aber bei keinem der Parameter umgewandelte Daten, sondern als ersten das jXHR-Objekt, was quasi ein standartisiertes XMLHttpRequest-Objekt ist. Warum er jetzt trotzdem .responseText aufruft, ist mir noch nicht ganz klar.

PS: Könntest Du bei Dir mal die "normale" Version von jQuery einbinden, also jene, die nicht minimiert wurde? Dann sehen wir auch, in welcher Zeile genau der Fehler auftritt.
 
Zuletzt bearbeitet:
@einfach nur crack ::
Hab jetzt eine normale Version geladen.
Version 1.11.2
Fehler :
if ( typeof xhr.responseText === "string" ) {
jquery.js (Zeile 9684)

@Cromon :
Hab noch mal mein ursprüngliches Skript verwendet. Stimmt, wenn ich es rumdrehe, bekomme ich keine Fehlermeldung mehr. Im Chrome bekomme ich das erwartete Verhalten, einen Dateidownload, mit einer funktionierenden Datei. Alle anderen Browser machen : NIX! Den Auszug aus dem FireBug habe ich mal in den Anhang gesetzt.

Ausserdem hab ich mal das ganze Projekt gezippt...
siehe file-stream.zip... ich muss aber jetzt nicht jqery umschreiben, oder? lol
 

Anhänge

  • file-stream.zip
    309 KB · Aufrufe: 6
  • screenshot.png
    screenshot.png
    65,9 KB · Aufrufe: 4
Hallo Netbull

Habe das ganze mal angesehen. Folgende Änderungen:
Serverseitig:
Sende die Daten als application/octet-stream und nicht als application/pdf. Offenbar akzeptiert firefox application/pdf nicht als gültige Antwort für responseType 'blob'. Also in der response.php einfach nur den folgenden content-typen angeben (du gibst ja jetzt 2 mal an, wobei der erste überschrieben wird):
header("Content-type: application/octet-stream");

Clientseitig:
Firefox hat gewisse Ansprüche an den link wenn du ihn als Download haben willst. Einerseits scheint createObjectURL nicht auf Anklang zu stossen, andererseits scheint das Element im DOM-Tree sein zu müssen, wenn du das click-event abfeuerst. Folgender Code downloadet im Firefox, Chrome das entsprechende PDF-File, im Internet Explorer geht es natürlich nicht, da dieser das "download"-Attribut nicht kennt:
Javascript:
    function loadDocument(element){
       console.log("jQuery Version : " + jQuery.fn.jquery)
       console.log("Initiate document download request");
       var requestObject = getRequestObject();
       
       requestObject.open('GET', '/file-stream/response.php', true);
       requestObject.responseType = 'blob';
       
       requestObject.onreadystatechange = function() {
           console.log("response readyState (" + requestObject.readyState + ") and status (" + requestObject.status + ")");
       
           if(requestObject.readyState == 4 && requestObject.status == 200) {
               console.log("Final Response has been taken!");
               if( requestObject.response.type!= "" ){
                   console.log("Seems to be a valid download ressource!");
                   var reader = new FileReader();
                   reader.onloadend = function () {
                       var a = document.createElement('a');
                       a.setAttribute('href', reader.result);
                       a.setAttribute('download', 'test.pdf');
                       a.style.display = 'none';
                       document.body.appendChild(a);
                       a.click();
                       document.body.removeChild(a);
                       console.log("Download has been done!");
                   }

                   reader.readAsDataURL(new Blob([requestObject.response], { type: 'application/pdf' }));            
                 
               } else {
                   console.log("Seems to be an invalid download ressource!");
                   console.log("Download gets aborted!");
               }
           }
       };
       requestObject.send();
    }

Viele Grüsse
Cromon
 
Zurück