Mehrere Dateien zum Download an den Browser senden

Die Dateien werden serverseitig zusammengestellt und an den Browser gesendet.

Für diese DEMO werden, je nach Benutzerauswahl, serverseitig mehrere Dateien zusammengestellt und in einer AJAX-Response zum Browser gesendet. Zur Auswahl stehen eine JavaScript-Datei, ein PerlModule und eine Grafikdatei. Entsprechend der Zusammenstellung und Anzahl der Dateien bringt der Browser genausoviele Download-Dialoge hervor, so dass der Benutzer ob der Verwendung entscheidet.

Dateien auswählen und Schaltfläche klicken: bSerialize.pm kuhschelle.jpg bSerialize.js

Erläuterungen

Zum Download mehrerer Dateien unterschiedlicher Content-Types findet in dieser Anwendung nur ein einziger Request-Response-Zyklus statt. Die Response ist abstrakt vergleichbar mit einer ZIP-Datei in welcher mehrere Dateien zusammengefasst sind, nur dass in dieser Anwendung die Response vom XHR-Objekt entgegengenommen und mittels JavaScript gleich ausgepackt wird.

Request

Für den AJAX-Request wurde in dieser Anwendung die Request-Methode GET festgelegt. Der String mit den Parametern enthält einen Schlüsselparameter und eine Liste mit den Dateinamen nach folgendem Schema:

    d=1;files=bSerialize.pm;files=bSerialize.js;files=kuhschelle.jpg

Als XHR-Response-Type wird ein ArrayBuffer angefordert. Aus der Sicht des Servers ist das eine ganz normale Byte-Sequenz.

Response

Serverseitig ergibt sich mit dem Parameter files ein Array. Es findet für jeden im Request gesendeten Dateinamen eine Prüfung statt, ob die jeweilige Datei zum Download freigegeben ist. Sofern das der Fall ist, sind Content-Type und der Pfad zur Datei gegeben und die Bytesequenz wird auf das Attribute bin gelesen. Alles zusammen ergibt einen abstrakten Datentype nach dem EAV-Muster (Entity, Attribute, Value):

# Bytesequenz in Attribute bin
# Entity => { Attribute => Value }
$VAR1 = {
      'bSerialize.pm' => {
                           'bin' => '',
                           'filename' => 'bSerialize.pm',
                           'path' => 'D:/home/files/fwlib/bSerialize.pm',
                           'type' => 'text/plain'
                         },
      'kuhschelle.jpg' => {
                            'bin' => '',
                            'filename' => 'kuhschelle.jpg',
                            'path' => 'D:/home/html/handwerkzeugs/astro/kuhschelle.jpg',
                            'type' => 'image/jpg'
                          },
      'bSerialize.js' => {
                           'bin' => '',
                           'filename' => 'bSerialize.js',
                           'path' => 'D:/home/html/handwerkzeugs/bSerialize.js',
                           'type' => 'text/plain'
                         }
        };

Zum Senden dieser Datenstruktur wird diese in eine Bytesequenz serialisiert (binary safe):

    my $bs = bSerialize->new;
    $self->{CONTENT} = $bs->eav2bin($eav) ? $bs->eav2bin($eav) : 1;

Und in der XHR-Callbackfunktion wird obenstehende Datenstruktur samt Binaries wiederhergestellt.

 // XHR Callback
 function download_cb(response){
    var eav = bSerialize.bin2eav(response, 'raw');
    for(ent in eav){
        var type = new StringView(eav[ent]['type']);
        var blob = new Blob( [eav[ent]['bin']], {type: type} );
        saveAs(blob, new StringView(eav[ent]['filename']))
    }
 }

Den Download-Dialog erzeugt die Funktion saveAs().

Serialize Algorithmus

Es versteht sich von selbst, dass zum Serialzieren serverseitig mit Perl derselbe Algorithmus auch clientseitig mit JavaScript zur Verfügung stehen muss. Siehe Dateien bSerialze.pm und bSerialize.js.


Anbieter: nmq​rstx-18­@yahoo.de, die Seite verwendet funktionsbedingt einen Session-Cookie und ist Bestandteil meines nach modernen Aspekten in Perl entwickelten Frameworks.