m.: Mehrere Downloads anstossen

Mahlzeit, ich hab hier eine Webanwendung die CSV-Dateien erzeugt. AKtuell werden einzelne Beiträge per Checkbox selektiert, dann per Dropdown eine Option ausgewählt und per Button die Datei erzeugt und an den Browser geschickt. Soweit, so gut. Jetzt will ich aber mehrere Dateien in einem Rutsch erzeugen. Die müssen aber an den Browser gesendet werden. Meine Überlegung: Ich erzeuge eine Datei und sende sie an den Browser. Dann erfolgt ein Redirect auf eine URL, die die nächste Datei erzeugt und senden usw. Gibt es evtl. ne einfachere Möglichkeit, mehrere Dateien automatisch an den Browser zu senden?

Es reicht, wenn es unter Chrome und Chromium funktioniert, andere Browser sind mir egal. Die komplette Webanwendung setzt einen dieser Browser voraus.

--
42
  1. Hallo m.,

    Gibt es evtl. ne einfachere Möglichkeit, mehrere Dateien automatisch an den Browser zu senden?

    Erzeuge alle Files, packe sie in ein ZIP-Archiv und sende das ZIP-Archiv an den User. Das ist die gängige Lösung.

    LG,
    CK

    1. Mahlzeit,

      Erzeuge alle Files, packe sie in ein ZIP-Archiv und sende das ZIP-Archiv an den User. Das ist die gängige Lösung.

      Danke für den Tip, das fällt aber aus. Ich brauch die Dateien einzeln und das entzippen auf nem Tablet ist zu aufwändig.

      --
      42
  2. Tach!

    Meine Überlegung: Ich erzeuge eine Datei und sende sie an den Browser. Dann erfolgt ein Redirect auf eine URL, die die nächste Datei erzeugt und senden usw.

    Definiere "dann"! Der Statuscode auf einen Request ist (neben anderen Codes) entweder 200 mit Inhalt oder 301/302, um dem Browser zu zeigen, dass die angeforderte Ressource woanders zu holen ist. Es gibt kein erst 200 dann 301/302.

    Gibt es evtl. ne einfachere Möglichkeit, mehrere Dateien automatisch an den Browser zu senden?

    Zum Beispiel mit Javascript mehrere Fenster öffnen, die jeweils einen Download anstoßen.

    dedlfix.

    1. Hallo dedlfix,

      Gibt es evtl. ne einfachere Möglichkeit, mehrere Dateien automatisch an den Browser zu senden?

      Zum Beispiel mit Javascript mehrere Fenster öffnen, die jeweils einen Download anstoßen.

      Don't. Das dürfte extrem verwirrend wirken und mit wahrscheinlich für Probleme sorgen.

      LG,
      CK

      1. Tach!

        Zum Beispiel mit Javascript mehrere Fenster öffnen, die jeweils einen Download anstoßen.

        Don't. Das dürfte extrem verwirrend wirken und mit wahrscheinlich für Probleme sorgen.

        Nun, wenn es sich, wie mir scheint, um eine Intranet-Anwendung handelt und man die Anwender schulen kann, muss man nicht zwingend Lieschen-Müller-Lösungen einsetzen. Ich kann nicht beurteilen, wie sich die Lösungen in die Umgebung einfügen, ich kann sie nur nennen und die Entscheidung dem Probleminhaber überlassen. Das ZIP auspacken zu müssen kann auch verwirrend sein. Jeder hat da ja so seine eigene Erwartungshaltung.

        dedlfix.

      2. Hallo und guten Morgen,

        Gibt es evtl. ne einfachere Möglichkeit, mehrere Dateien automatisch an den Browser zu senden?

        Zum Beispiel mit Javascript mehrere Fenster öffnen, die jeweils einen Download anstoßen.

        Don't. Das dürfte extrem verwirrend wirken und mit wahrscheinlich für Probleme sorgen.

        Geht ja ohnehin nicht bei jedem Browser in Normalzustand. Die Anzahl gleichzeitiger Requests auf eine Domain ist immer noch begrenzt, auch, wenn sie inzwischen größer als zwei ist..

        Grüße
        TS

        --
        es wachse der Freifunk
        http://freifunk-oberharz.de
        1. Mahlzeit,

          Geht ja ohnehin nicht bei jedem Browser in Normalzustand. Die Anzahl gleichzeitiger Requests auf eine Domain ist immer noch begrenzt, auch, wenn sie inzwischen größer als zwei ist..

          Wenn ich was umstellen muss, wäre es kein Problem, bin der einzige Anwender. Es geht um maximal 5 Dateien, jede maximal 10kB gross

          --
          42
    2. Hallo,

      Gibt es evtl. ne einfachere Möglichkeit, mehrere Dateien automatisch an den Browser zu senden?

      Zum Beispiel mit Javascript mehrere Fenster öffnen, die jeweils einen Download anstoßen.

      oder mehrere httpRequests abschicken.

      Gruß
      Jürgen

    3. Mahlzeit,

      Zum Beispiel mit Javascript mehrere Fenster öffnen, die jeweils einen Download anstoßen.

      Nicht meine Traumlösung aber ne Überlegung wert. Da nur ich damit arbeite, ist es egal, wenn es andere verwirrt ;)

      --
      42
  3. hier kommen 2 Textdateien und eine Grafik als Beispiel. Die Zusammenstellung kann'st natürlich auch variabel machen, der Browser bringt entsprechend viele Download-Dialoge. Test es mal, über die Lizenzen meiner Libraries müssen wir reden.

    1. Hallo pl,

      hab mal draufgeklickt. Als erster Eintrag im Chrome Log kommt sofort

         GET http://handwerkzeugs.de/bSerialize.js 403 (URLBlocked)  
      

      er scheint wohl XSS zu vermuten. Ich sehe zwar nicht, wo das auf der Seite steht, aber es kommt ja vielleicht indirekt irgendwoher mit. Weißt Du bestimmt besser als ich...

      Klicke ich dann auf den Button, kommt "multidownload.html:118 Uncaught ReferenceError: bSerialize is not defined" - das wird sicher ein Folgefehler sein.

      Rolf

      1. Hallo,

        hab mal draufgeklickt. Als erster Eintrag im Chrome Log kommt sofort

           GET http://handwerkzeugs.de/bSerialize.js 403 (URLBlocked)  
        

        er scheint wohl XSS zu vermuten.

        Nein, es war nur eine blöde Umleitung. Problem ist behoben ;)

        Danke für Deinen Hinweis, wennst magst, bitte testen.

        MfG

    2. Hallo,

      hier kommen 2 Textdateien und eine Grafik als Beispiel.

      da kommt genau eine HTTP-Ressource, die du mit Javascript in ihre Bestandteile zerlegst. Kann man natürlich machen, sind aber technisch gesehen nicht "mehrere Downloads".
      Und ohne Javascript geht mal gar nichts.

      Unterm Strich nicht wirklich, was ich eine Lösung nennen würde.

      So long,
       Martin

      --
      Nothing travels faster than the speed of light with the possible exception of bad news, which obeys its own special laws.
      - Douglas Adams, The Hitchhiker's Guide To The Galaxy
      1. Ob das eine Lösung ist müsste wohl der OP entscheiden.

        Die Technik ist jedenfalls interessant. Funktioniert das auch im Internet Explorer?

        Rolf

      2. Hallo,

        hier kommen 2 Textdateien und eine Grafik als Beispiel.

        da kommt genau eine HTTP-Ressource, die du mit Javascript in ihre Bestandteile zerlegst. Kann man natürlich machen, sind aber technisch gesehen nicht "mehrere Downloads".

        Natürlich ist es nur eine Response, weil es nur ein Request ist. Die entsprechend Benutzerauswahl serverseitig zusammengestellten Dateien werden samt weiterer Angaben wie Name, Type usw. in eine Sequenz (siehe Dateibegriff) serialisiert. In der Callbackfunktion wird die Sequenz deserialisiert und erzeugt zunächst ein JS-Datenobjekt. Danach werden die Datein bytegenau und binary safe wiederhergestellt und je Datei wird ein SaveAs-Dialog erzeugt.

        In der DEMO ist die Auswahl bisher fest kodiert. Fortsetzung folgt.

        Tags: ArrayBuffer, Uint8Array, Blob, MDN

        1. Hallo pl,

          ein Response, ein Request - binary safe. Das klingt nachvollziehbar (und für mich vielversprechend).

          Die Frage, die sich mir in diesem Kontext jedoch stellt, ist: Ist der Response idempotent?

          Denn angenommen der Request ist in Form eines Byte-Buffers sequentiell an den Webserver übermittelt. Das Handling "ein Request=ein Response" ist in diesem Fall unter anderem aufgrund der Singularität des HTTP-Protokolls natürlich gewährleistet, da stimme ich mit Dir überein.

          Was passiert nun aber, wenn der Client einen multipart Request mit chunked transfer encoding sendet? Behält der Server diese Zuständigkeiten bei, oder verliert er sich in scattered chunks? Und was, wenn ein deprecated encoding mitgesendet wird?

          In der Therorie kann ich deinem Ansatz folgen, aber in der Praxis komme ich nicht an den potenziellen Client-Proxies vorbei - die ja, wie wir alle in unserer langjährigen Berufslaufbahn als professionelle ITler zu Genüge erfahren haben - oft unerwartete Folgen mit sich ziehen (siehe Beispiel Toll-Collect oder Coca Cola).

          Wie wirken sich Port-forwardings auf o.g. Problemstellung aus?

          Ich kann mir vorstellen, dass z.B. ein invalider accept-header diesem Lösungsansatz in die Quere kommen kann, da der Workflow einen genormten Verlauf voraussetzt - der aber in einem solchen Fall eben nicht gegeben ist (leider).

          Alles in allem ein spannender Ansatz. Ich würde mich über einen weiteren Austausch freuen.

          Vielen Dank & liebe Grüße, Kristoff

          PS: Ich bin durchaus bereit über deine besagten Lizenzgebühren zu reden. Denn sollten sich meine Bedenken beseitigen, sehe ich hier eine sehr große und vor allem langfristige Synergie.

          PPS: Über deine Fortsetzung bin ich sehr gespannt. (Alleine deswegen habe ich mir den RSS-Feed abonniert :-)

          1. BINGO

            Vielen Dank, damit habe ich den 1. Preis gewonnen.

          2. Hallo und guten Morgen,

            Ist der Response idempotent?

            Kannst Du das auch auf deutsch fragen? :-P

            Hängt das nicht auch vom Request-Header ab? Der könnte ja auch ein "If-Modified-Since ..." enthalten. Dann würde der Server im Normalfall nur einen Status 304 und Header "Last-Modiefied ..." zurücksenden, aber keine Nutzdaten.

            Woher bekommt das Modul dann seine Daten? Wie kann das auf den Cache zugreifen?

            MMn kann man das (mit JS) nicht programmieren, ohne in den Browser einzugreifen. Also Plug-In erscheint mir möglich, JS-Script (also ohne Java oder Flash oder sontige Plug-Ins) glaube ich nicht dran.

            Grüße
            TS

            --
            es wachse der Freifunk
            http://freifunk-oberharz.de
            1. Hallo TS,

              danke für deinen qualitativen Beitrag.

              Hängt das nicht auch vom Request-Header ab? Der könnte ja auch ein "If-Modified-Since ..." enthalten.

              Das habe ich in der Tat nicht genügend bedacht! Auf den ersten Blick könnte man dem mit einer transaktionellen Cache-Policy Sorge tragen. Wobei man hierbei natürlich aufpassen muss, dass kein rekursiver Tree-Select seitens der embedded protocols auftritt. Ich denke jedoch, dass man an dieser Stelle mit konservativen Methodiken seinen Weg finden kann - sei es mittels eines grep -Hirn's oder einer post-mortem-Analyse von ps -aux. Hiermit haben sich schon weit klügere Köpfe beschäftigt, deren Ergebnisse man sich durchaus zu Nutzen machen kann.

              Dann würde der Server im Normalfall nur einen Status 304 und Header "Last-Modiefied ..." zurücksenden, aber keine Nutzdaten.

              Ja, auch nicht schlecht. Bzw. doch, denn das ganze o.g. Prinzip basiert ja (leider) auf der Auswertung der Request-Parameter. Obwohl.. wenn die in einem assoziativen Array transferiert werden, sollte dieses Problem eigentlich gar nicht auftreten.

              Woher bekommt das Modul dann seine Daten? Wie kann das auf den Cache zugreifen?

              Siehe oben. Mittels einer transaktionellen Cache-Policy.

              MMn kann man das (mit JS) nicht programmieren, ohne in den Browser einzugreifen. Also Plug-In erscheint mir möglich, JS-Script (also ohne Java oder Flash oder sontige Plug-Ins) glaube ich nicht dran.

              Naja, das sehe ich etwas anders. Denn meine langjährige Erfahrung als Main-Submitter von shumway hat mich anderes gelehrt. Das ist natürlich ein hoch-komplexes Thema - aber es ist dennoch machbar.

              Die Emulierung nicht typisierter Sprachen hin zu thread-safe-Singletons kann mitunter schon echt anstrengend sein. Aber wenn man das Prinzip einmal verstanden hat, eröffnen sich sublime Möglichkeiten. Ich werde zu diesem Thema noch einen intensiven Blogpost verfassen - evtl. mit Beispielcode.. obwohl, ich muss erst einmal schauen, welche Lizenmodelle hierfür in Frage kämen.

              Aber ich empfinde, dass wir, zusammen mit deinen guten Einwänden, durchaus einen qualitativ hochwertigen und vor allem wirtschaftlich erfolgreichen Lösungsansatz zustande bringen können.

              Das ist das Schöne an solchen Austauschen!

              In Frieden, Kristoff

          3. Hallo pl,

            ein Response, ein Request - binary safe. Das klingt nachvollziehbar (und für mich vielversprechend).

            Die Frage, die sich mir in diesem Kontext jedoch stellt, ist: Ist der Response idempotent?

            Denn angenommen der Request ist in Form eines Byte-Buffers sequentiell an den Webserver übermittelt.

            Der Request ist ein GET mit einem ganze normalen QUERY_STRING und das ist selbstverständlich idempotent. HTTP ist selbstverständlich auch transparent, gzip oder nicht gezip, chunked oder nicht chunked ist für die Anwendung völlig unerheblich.

            Proxies kannst selber testen hier nun sind die Libs auch auswählbar.

            Abstrakt gesehen entspricht meine Variante einem native Request/Response mit ZIP-Datei, nur dass ich das halt mit AJAX mache und JavaScipt das Auspacken übernimmt und dass anstelle ZIP anders serialisiert wird.

            PS: Eure Bewertung ist mal wieder idiotisch.

      3. hier kommen 2 Textdateien und eine Grafik als Beispiel.

        da kommt genau eine HTTP-Ressource, die du mit Javascript in ihre Bestandteile zerlegst.

        Und zwar komplett im Hauptspeicher, das kann nur bis zu einer bestimmten Grenze gut gehen.

        1. Ja. Seinen Datenbank-Backup sollte man darüber nicht anfordern :)

          1. Ja. Seinen Datenbank-Backup sollte man darüber nicht anfordern :)

            Klar, über JS ist das unsinnig, aber über'n Webservice isses kein Problem. Mein Perl-Modul bSerialize.pm kann sogar Datentypen, also auch NULL. Aber ich hab schon lange keine MySQL-Tabellen mehr hin und her geschafft ;)

            Untenstehend meine Manager-Kommandozeile mit Beispiel einer SQL Anweisung. Für Dateienübertragungen kommen meine bewährten Serializer zum Einsatz ;)

            D:\>.pl
            Kommandozeilen-Framework
            =========================
              Der Name der Klasse wird als erstes Argument übergben,
              weitere Optionen stellt die Klasse bereit.
            
            Klassenübersicht:
            =========================
              RPC:   Remote Procedure Call
              Date:  Klasse zum Testen einer Datumeingabe
              RDBM:  Remote Datenbank Manager
              BOT:   Teste rolfrost.de
              RDBF:  DBF rolfrost.de erstellen
              PROXY: ProxyServer von us-proxy.org abrufen
            
            
            D:\>.pl RPC
            Remote CMD auf dem Host
            --attribute, -a: Zeigt Attribut+Value einer Entity in Konfiguration
            --base, -ba: Name der Datenbank für Option --sql
            --binary, -bi: Erzeuge die Konfiguration als Binary
            --cmd, -c: Freies Kommando im aktuellen Verzeichnis
            --dump, -d: Dump Response Object
            --entity, -e: Zeigt Attribute einer Entity in Konfiguration
            --files, -f: Lokale Dateien für Upload
            --head, -he: HEAD Request auf URL
            --host, -ho: rolfrost.de oder rolfrost
            --irc, -i: Chatserver starten
            --request, -r: HTTP Request auf den angegebenen URL oder auf alle URLs
            --sql, -s: SQL Anweisung, erfordert --base
            --urls, -u: Listet URLs in Konfiguration
            
            D:\>.pl RPC -ho rolfrost.de -base myweb -sql select version()
            $VAR1 = [
                      {
                        'version()' => '5.6.28-log'
                      }
                    ];
            
        2. hier kommen 2 Textdateien und eine Grafik als Beispiel.

          da kommt genau eine HTTP-Ressource, die du mit Javascript in ihre Bestandteile zerlegst.

          Und zwar komplett im Hauptspeicher, das kann nur bis zu einer bestimmten Grenze gut gehen.

          Ja, wer hätte das gedacht! Im Übrigen hat es lang genug gedauert, bis Browser mit Multimediadateien umgehen können: Vom Beginn des Multi-Media-Zeitalters an sind da immerhin mehr als 15 Jahre ins Land gegangen.

          Der in bSerialze.js|.pm implementierte Serializer nutzt hier beschriebene Algorithmen womit sich CLient- wie serverseitig genau dieselben Datenstrukturen ergeben. Es versteht sich von selbst, dass zum Serialzieren serverseitig mit Perl derselbe Algorithmus auch clientseitig mit JavaScript zur Verfügung stehen muss. Und ja, mit PHP hab ich diesen einfachen Algorithmus auch schon umgesetzt.

          Download einer Multimediadatei und Wiederherstellung der Komponenten unterschiedlicher Content-Types.

      4. Mahlzeit,

        Unterm Strich nicht wirklich, was ich eine Lösung nennen würde.

        Wenn es aufm Tablet (Android 4.4, Chrome-Dev) funktioniert, is mir wurscht ob Javascript oder nicht. Diese Lösung muss eh nur noch 4.6 Monate laufen, dann stell ich auch ein neues System um und brauch es nicht mehr

        --
        42
    3. Mahlzeit,

      hier kommen 2 Textdateien und eine Grafik als Beispiel. Die Zusammenstellung kann'st natürlich auch variabel machen, der Browser bringt entsprechend viele Download-Dialoge. Test es mal, über die Lizenzen meiner Libraries müssen wir reden.

      Funktioniert zumindest auf dem Desktop im Chrome unter Linux. Auf dem Tablet muss ich testen und dann sehen ob ich das in mein Framework einbauen kann. Ist nur für mich allein um etwas Zeit zu sparen, also nix für das ich Geld ausgeben würde ;)

      --
      42
      1. Mahlzeit,

        hier kommen 2 Textdateien und eine Grafik als Beispiel. Die Zusammenstellung kann'st natürlich auch variabel machen, der Browser bringt entsprechend viele Download-Dialoge. Test es mal, über die Lizenzen meiner Libraries müssen wir reden.

        Funktioniert zumindest auf dem Desktop im Chrome unter Linux. Auf dem Tablet muss ich testen und dann sehen ob ich das in mein Framework einbauen kann. Ist nur für mich allein um etwas Zeit zu sparen, also nix für das ich Geld ausgeben würde ;)

        Untenstehend der Serialize-Algorithm. Für'n Array werden die Sequenzen ganz einfach aneinandergehängt, siehe array bin. Die Anwendung letztendlich nutzt eav2bin. Für PHP kein Problem, das umzusetzen. Den $cache kannst Du auch weglassen, der lohnt sich nur, wenn viele Attribute den gleichen Wert haben (z.B. type = 'text/plain').

        # PHP EAV Example
        $eav['entity']['attribute']   = 'value';
        $eav['bSerialize.js']['type'] = 'text/plain';
        $eav['bSerialize.js']['bin']  = 'hier den Inhalt der Datei';
        
        # Perl
        # Kleinste atomare Einheit
        sub val2bin{
            my $self = shift;
            my $val = shift;
        
            return pack('NC',0,0) if ! defined $val;
            
            my %cache = %{$self->{valcache}};
            return $cache{$val} ? $cache{$val} : do{
                my $bs = pack('NC', length($val), 1).$val; 
                $cache{$val} = $bs;
                $bs;
            };
        }
        
  4. Hier noch eine andere Variante: Für jede Datei ein Request, siehe Beschreibung auf Seite.