Ernst: AJAX Preview von Bild

Hallo,

mittels einer Form wird über ein <input type="file">-Element ein Bild hochgeladen.

Nun soll eine Preview-Funktion realisiert werden, d.h. auf eine Benutzeraktion (z.B. Klick auf einen "Preview"-Button) wird in einem Bereich der Seite ein thumbnail des Bildes angezeigt, ohne die Seite neu zu laden.
Dies soll analog zum asynchronen Hochladen von anderer Information mittels dem XMLHttpRequest-Objekt geschehen. Auf dem Server wird das Bild skaliert und an den Client zurückgesandt, der den Response entsprechend verarbeitet.

Meine Frage: (Wie) Kann ich über Javascript einen MIME-Block mit dem Bild zusammenbasteln, das im <input type="file">-Element ausgewählt ist? Eine nichtproprietäre Lösung wäre ideal.

Vielen Dank im voraus
Ernst

  1. Hallo Ernst.

    Meine Frage: (Wie) Kann ich über Javascript einen MIME-Block mit dem Bild zusammenbasteln, das im <input type="file">-Element ausgewählt ist?

    Gar nicht, da JavaScript keinen Zugriff auf das Dateisystem hat.

    Einen schönen Samstag noch.

    Gruß, Mathias

    --
    sh:( fo:} ch:? rl:( br: n4:~ ie:{ mo:| va:) de:> zu:} fl:( ss:) ls:[ js:|
    debian/rules
    1. Meine Frage: (Wie) Kann ich über Javascript einen MIME-Block mit dem Bild zusammenbasteln, das im <input type="file">-Element ausgewählt ist?

      Gar nicht, da JavaScript keinen Zugriff auf das Dateisystem hat.

      Kann ich denn nicht vielleicht über eine browserspezifische API den Browsermechanismus nutzen, der beim Hochladen der Form ja auf die Datei zugreift und in einem entsprechenden MIME-Block kodiert? Das wäre immerhin kein direkter Zugriff auf das Dateisystem, sondern die über den Browser gekapselte Nutzung eines sowieso ablaufenden (und durch die Auswahl des Nutzers im <input type="file">-Element auch genau definierten) Dateizugriffs, also auch keine Sicherheitslücke.

      Wenn es nicht über AJAX geht, gibt es dann eine andere generell funktionierende Möglichkeit, die ausgewählte Datei asynchron hochzuladen, ohne die Browsereinstellungen ändern zu müssen?

      Danke und Gruss
      Ernst

      1. Moin!

        Irgendwie habe ich den Eindruck, daß Du wohl noch nicht ganz verstanden hast, was AJAX ist.

        Wie auch immer... Was Du vorhast geht nur so:
        1. Per XMLHttpRequest schickst Du das Bild zum Server
        2. Per zweitem XMLHttpRequest lädst Du das hochgeladene Bild wieder vom Server
        Ab da hast Du vollen Zugriff auf das Bild, genauer, auf die, vom Server  geladene Version

        -- Skeeve

        1. Lieber Skeeve,

          Wie auch immer... Was Du vorhast geht nur so:

          1. Per XMLHttpRequest schickst Du das Bild zum Server
          2. Per zweitem XMLHttpRequest lädst Du das hochgeladene Bild wieder vom Server
            Ab da hast Du vollen Zugriff auf das Bild, genauer, auf die, vom Server  geladene Version

          EINWAND! Was spricht dagegen, bereits die XMLResponse des ersten Requests entsprechend für eine Rückmeldung zu nutzen? Im Zurückgegebenen XML könnte sowohl die neue Resource, als auch gleich das <img>-Element zum Einbinden in den DOM-Baum enthalten sein... käme eben auf die serverseitige "Kontaktstelle" des Uploads an...

          Liebe Grüße aus Ellwangen,

          Felix Riesterer.

        2. Moin!

          Moin!

          Irgendwie habe ich den Eindruck, daß Du wohl noch nicht ganz verstanden hast, was AJAX ist.

          Mit deiner Antwort hier beweist DU aber auch, dass du noch nicht verstanden hast, was AJAX ist.

          Wie auch immer... Was Du vorhast geht nur so:

          1. Per XMLHttpRequest schickst Du das Bild zum Server

          Das geht eben NICHT! XMLHttpRequest kann nur Dinge verschicken, auf die Javascript im Browser Zugriff hat. Auf der Festplatte des Clients abgelegte Bilddateien gehören NICHT dazu.

          1. Per zweitem XMLHttpRequest lädst Du das hochgeladene Bild wieder vom Server

          Weil es kein hochgeladenes Bild gibt, kann man es auch nicht wieder herunterladen.

          Ab da hast Du vollen Zugriff auf das Bild, genauer, auf die, vom Server  geladene Version

          Eben nicht!

          - Sven Rautenberg

          --
          "Love your nation - respect the others."
        3. Hallo,

          Irgendwie habe ich den Eindruck, daß Du wohl noch nicht ganz verstanden hast, was AJAX ist.

          Ich denke schon, immerhin nutze ich es schon eine Weile.
          Allerdings glaube ich, dass Du meine Frage nicht ganz verstanden hast: Mir geht es nicht um die Kommunikation an sich, sondern um den javascript-Zugriff auf die Bild-Ressoure. Wie ich per javascript asynchron mit einem Server kommuniziere, ist mir klar.

          Wie auch immer... Was Du vorhast geht nur so:

          1. Per XMLHttpRequest schickst Du das Bild zum Server
          2. Per zweitem XMLHttpRequest lädst Du das hochgeladene Bild wieder vom Server
            Ab da hast Du vollen Zugriff auf das Bild, genauer, auf die, vom Server  geladene Version

          Wieso ist ein zweiter Request nötig? Der Response, der auf den ersten Request folgt, kann doch schon das formatierte Bild und weitere Informationen enthalten, die dann platziert werden!
          Wenn Du immer so vorgehst und für eine einfache Request/Response-Kommunikation zwei Request abschickst, solltest Du Deine Strategie noch einmal überdenken... Oder habe ich Dich jetzt falsch verstanden?

          Gruss
          Ernst

        4. Moin!

          Ich antworte mir einfach selbst, statt allen dreine zu antworten. ;-)

          Ihr habt natürlich Recht. Man kann natürlich schon in die Antwort das skalierte Bild packen.

          Und ja: Per XMLHttpRequest bekomme ich so ein Bild wohl kaum hochgeladen. Da habe ich mich ziemlich verhauen ;-) Man muß natürlich ein Formular abschicken um eine Datei hochzuladen.

          -- Skeeve

      2. Moin!

        Gar nicht, da JavaScript keinen Zugriff auf das Dateisystem hat.

        Kann ich denn nicht vielleicht über eine browserspezifische API den Browsermechanismus nutzen, der beim Hochladen der Form ja auf die Datei zugreift und in einem entsprechenden MIME-Block kodiert?

        Nein, das ist nicht möglich.

        Es geht kein Weg daran vorbei: HTTP-Dateiuploads mit Formularen und dem file-<input> funktionieren nur durch klassisches Submitten des POST-Formulars.

        Du kannst dabei allerdings beliebig "tricksen", denn nirgendwo steht geschrieben, dass das Formular im gleichen Browserfenster seine Antwort zeigen muß. Das target-Attribut existiert auch für <form>, es ist also problemlos möglich, die Formularantwort in unsichtbaren Frames oder passend platzierten IFrames "anzuzeigen" und auszuwerten.

        - Sven Rautenberg

        --
        "Love your nation - respect the others."
        1. Das ist eine akzeptable Lösung. Danke!

          Gruss
          Ernst

  2. Hallo,

    auf die Gefahr hin, dass ich Dich missverstehe:

    Um zeitnah ein Preview-Bild während des Hochladens anzuzeigen, könntest Du den Pfad aus dem File-Upload-Formularfeld auslesen und als img-Element in Deiner Seite einbinden. Die Skalierung müßtest Du über width und height des img-Elements vornehmen, was möglicherweise etwas auf die Darstellungsqualität des Vorschaubildes geht.
    So könntest Du jedenfalls während des Uploads ein Vorschaubild anzeigen und müßtest nicht einmal den Server kontaktieren ;)

    Ciao

    1. Moin!

      *PATSCH* (Mit flacher Hand vor Stirn hau).... Daß ich darauf nicht gekommen bin...

      -- Skeeve

    2. Hallo schneemann.

      Um zeitnah ein Preview-Bild während des Hochladens anzuzeigen, könntest Du den Pfad aus dem File-Upload-Formularfeld auslesen und als img-Element in Deiner Seite einbinden.

      Einfache aber geniale Idee. Es hat sich als funktionstüchtig erwiesen im Firefox, IE und Konqueror. Nicht funktionstüchtig ist es im Opera (hier kann nur der Dateiname ohne Pfad aus dem Dateiuploadfeld ausgelesen werden) und im Safari (hier wird zwar der vollständige Pfad ausgelesen, doch dann nicht auf file:/// bezogen).

      Mit ein wenig Mehraufwand könnte man dies jedoch sicher auch im Safari hinbekommen. Bzgl. Opera werde ich wohl einmal eine Feature-Request einsenden.

      Einen schönen Sonntag noch.

      Gruß, Mathias

      --
      sh:( fo:} ch:? rl:( br: n4:~ ie:{ mo:| va:) de:> zu:} fl:( ss:) ls:[ js:|
      debian/rules
      1. Hallo schneemann, Mathias

        Um zeitnah ein Preview-Bild während des Hochladens anzuzeigen, könntest Du den Pfad aus dem File-Upload-Formularfeld auslesen und als img-Element in Deiner Seite einbinden.

        Einfache aber geniale Idee.

        Da kann ich nur zustimmen, danke!

        Es hat sich als funktionstüchtig erwiesen im Firefox, IE und Konqueror.

        Für den IE kann ich das bestätigen. Im FF funktionert es bei mir nicht. Wenn man sich den DOM Tree anguckt, ist zwar ein korrektes <img>-Element erzeugt worden, es wird allerdings nicht angezeigt. Anscheinend darf eine aus dem Netz geladene Seite nicht auf eine lokale Datei zugreifen: http://www.firefox-browser.de/wiki/Lokale_Bilder.

        @Mathias: Hast Du in user.js die Rechte entsprechend gesetzt, um die Sicherheitssperre zu umgehen?

        Gruss
        Ernst

        1. Hallo Ernst.

          Es hat sich als funktionstüchtig erwiesen im Firefox, IE und Konqueror.

          Für den IE kann ich das bestätigen. Im FF funktionert es bei mir nicht. Wenn man sich den DOM Tree anguckt, ist zwar ein korrektes <img>-Element erzeugt worden, es wird allerdings nicht angezeigt. Anscheinend darf eine aus dem Netz geladene Seite nicht auf eine lokale Datei zugreifen: http://www.firefox-browser.de/wiki/Lokale_Bilder.

          Achja, stimmt.

          @Mathias: Hast Du in user.js die Rechte entsprechend gesetzt, um die Sicherheitssperre zu umgehen?

          Das nicht. Ich hatte mein Script zuerst nicht über HTTP getestet, sondern nur per lokalem Dateiaufruf.

          Und offenbar ist die Umsetzung auch in Konqueror und Safari doch nicht möglich. Ein dem Pfad zur Grafik voran gestelltes „file://“ bringt nicht den erhofften Effekt.

          Somit läuft es im WWW offenbar einzig und allein im IE, was diese Lösung ebenfalls weniger lukrativ erscheinen lässt. Schade.

          Einen schönen Sonntag noch.

          Gruß, Mathias

          --
          sh:( fo:} ch:? rl:( br: n4:~ ie:{ mo:| va:) de:> zu:} fl:( ss:) ls:[ js:|
          debian/rules