klaus: File-Upload mit AJAX und PHP

Hallo alle zusammen,

stehe vor folgendem Problem: Ich muss über unser CMS eine Datei vom lokalen Host auf den Server hochladen. Jedoch läuft das CMS mit AJAX. Und da ist - soviel hab ich schon herausgefunden - ein File-Upload eine schwer lösbare Aufgabe.

Mein Aufruf sieht folgendermassen aus:

  
-- SNIP --  
<form action="PHP_SELF" enctype="multipart/form-data" method="post" name="upload_form">  
  <input type="hidden" name="MAX_FILE_SIZE" value="16000000">  
  Upload-File:<input name="xml_file" type="file" accept="text/xml">  
  <input type='button' onclick="document.upload_form.bereich_auswertung.value='...'; readSendForm(document.upload_form); return document.returnValue; this.form.submit()" style="background-image: url(/img/button_02.gif)">  
</form>  
-- SNAP --  

Und die dazugehörenden JavaScripts:

[code lang=javascript]
function readSendForm(pFormId)
{
 if(http_request==false)
 {
  //Formularinformationen
  var form = pFormId;
  var fAction = pFormId.action;
  var fMethod = pFormId.method;
  var fEnctype = pFormId.enctype;

// Belegung Standardwert:
  if(fEnctype == '') fEnctype = 'application/x-www-form-urlencoded';

errors = '1';
  info = '';
  makePOSTRequest(fAction, fMethod, info, fEnctype, readSendForm);
  document.returnValue = (errors == '');
 }
 else
 {
  if (http_request.readyState == 4)
  {
   if (http_request.status == 200)
   {
    result = http_request.responseText;
   }
   else
   {
    // Fehlermeldung
   }
   http_request=false;
  }
 }
}

function makePOSTRequest(pUrl, pMethod, pContent, pType, pFunction)
{
-- SNAP --
.
.
.
-- SNIP --
 if(pMethod=='Get' || pMethod=='GET' || pMethod=='gGet')
 {
  urlString = pUrl+'?'+pContent;
  http_request.open('GET', urlString, true);
  http_request.onreadystatechange = pFunction;
  http_request.send(null);
 }
 else
 {
  http_request.onreadystatechange = pFunction;
  http_request.open('POST', pUrl, true);
  http_request.setRequestHeader("Content-type", pType);
  http_request.setRequestHeader("Content-length", pContent.length);
  http_request.setRequestHeader("Connection", "close");
  http_request.send(pContent);
 }
}
[/code ]

Result gibt einen Wert zurück (nämlich genau den Quelltext der Page), $_FILES ist jedoch leer und die Auswertungsseite wird auch nicht aufgerufen. Es scheint, als wäre der 'this.form.submit()'-Aufruf komplett wirkungslos.

Was muss ich noch umsetzen, damit der Fileupload funktioniert?

LG Klaus

  1. Nicht schwer lösbar.

    Per Ajax ist ein Upload _unmöglich_ (Sicherheitsvorkehrung)

    1. Nicht schwer lösbar.

      Per Ajax ist ein Upload _unmöglich_ (Sicherheitsvorkehrung)

      Nichts ist unmöglich! Es gibt für jedes Problem immer eine Lösung - es stellt sich nur die Frage, wie lang man bereit ist, diese zu suchen. Bin also für weitere, konstruktivere Lösungsanzätze offen und dankbar!!

      1. Per Ajax ist ein Upload _unmöglich_ (Sicherheitsvorkehrung)

        Nichts ist unmöglich!

        Doch!

        Per AJAX ist ein Dateiupload unmöglich, weil Javascript keinerlei Zugriff auf lokal gespeicherte Dateien hat.

        Wenn du aber mit Javascript nicht an die Datei herankommst, die per AJAX hochgeladen werden soll, kannst du den Dateiinhalt auch nicht in den AJAX-POST-Request packen. So einfach ist das.

        Zum Dateiupload ist immer noch ein stinknormales Formular mit einem stinknormalen Submit-Vorgang erforderlich.

        Dass man zur Wahrung des AJAX-Scheins das Upload-Ergebnis ggf. in ein winziges IFRAME (mit target im <form>) schickt, oder den Upload mit HTTP-Statuscode 204 beantwortet, ist eine komplett andere Geschichte. Aber solch ein Vorgang ist nicht AJAX.

        Es gibt für jedes Problem immer eine Lösung - es stellt sich nur die Frage, wie lang man bereit ist, diese zu suchen.

        Finde einfach heraus, wie du per Javascript auf den Inhalt lokal gespeicherter Dateien zugreifen und diese auslesen kannst, und schon wirst du reich - entweder, weil du diese Methode als Zero-Day-Exploit teuer an interessierte Bösewichte verkaufen, oder weil du dann als gefragter Experte über passende Kongresse tingeln kannst.

        1. Dass man zur Wahrung des AJAX-Scheins das Upload-Ergebnis ggf. in ein winziges IFRAME (mit target im <form>) schickt, oder den Upload mit HTTP-Statuscode 204 beantwortet, ist eine komplett andere Geschichte. Aber solch ein Vorgang ist nicht AJAX.

          Genau in diese Richtung zielt meine Anfrage. Auf dieses Datei-Upload-Feld hat kein normaler Benutzer der Homepage Zugriff, sondern nur autorisierte User, die die jeweiliige Berechtigung im AdminBereich des CMS besitzen. Ganz nebenbei läuft das CMS im Normalfall nicht im normalen Web.

          1. Auf dieses Datei-Upload-Feld hat kein normaler Benutzer der Homepage Zugriff, sondern nur autorisierte User, die die jeweiliige Berechtigung im AdminBereich des CMS besitzen.

            Ja und? Wer was darf, interessiert den Uploadmechanismus nicht.

            1. Auf dieses Datei-Upload-Feld hat kein normaler Benutzer der Homepage Zugriff, sondern nur autorisierte User, die die jeweiliige Berechtigung im AdminBereich des CMS besitzen.

              Ja und? Wer was darf, interessiert den Uploadmechanismus nicht.

              Mein Gott, das war doch nur eine Erklärung, worum es da genauer geht!!! Ein bisschen (Weiter-)Denken erwart ich mir eigentlich von den Spezialisten hier schon! Gibt es hier denn wirklich niemanden, der anstatt immer gleich 'unmöglich' und 'nicht machbar' zu schreien konstruktive Lösungsansätze von sich gibt?

              1. Mein Gott, das war doch nur eine Erklärung, worum es da genauer geht!!! Ein bisschen (Weiter-)Denken erwart ich mir eigentlich von den Spezialisten hier schon! Gibt es hier denn wirklich niemanden, der anstatt immer gleich 'unmöglich' und 'nicht machbar' zu schreien konstruktive Lösungsansätze von sich gibt?

                Den hast du doch bereits bekommen?
                Was hast du daran nicht verstanden?

                Struppi.

                --
                Javascript ist toll (Perl auch!)
                1. @struppi:

                  Den hast du doch bereits bekommen?
                  Was hast du daran nicht verstanden?

                  Ganz EINFACH: WIE SOLL / KANN ICH DAS AUF EINFACHE ART UMSETZEN??? Was ist da so schwer zu verstehen?

                  Wenn ich wissen würde, wie ich das einfach umsetzen kann (komplizierte Varianten mit cgi-bin und Progressbar und sonstigem Schnickschnack gibts ja genug), würd ich ja nicht hier im Forum nachfragen, oder!?. Mich interessiert nur eine möglichst einfache Variante, die innerhalb kürzester Zeit implementierbar ist.

                  @wahsaga:

                  Hast du doch bereits bekommen - vielleicht nur noch nicht verstanden?

                  Endlich mal einer, der den Nagel auf den Kopf trifft

                  @marc:

                  Man kann den upload natürlich in ein iFrame verlagern. Das ist _nicht_ ajax.
                  Warum hast Du nicht so weit gedacht?

                  Bin halt nicht so ein Freak hinsichtlich JavaScript wie andere hier im Forum (auch das soll es geben, man glaubt es kaum).

                  1. *lol* Soll das eine subtile Beleiduigung sein? Ich bin garantiert kein JS-Freak, das merke ich viel zu oft.

                    Zum Prinzip:

                    Du bettest eine (PHP-)Seite (uploadseite) in ein iFrame auf deiner eigentlichen Seite ein. Diese uploadseite enthält ein komplettes Formular zum Fileupload.

                    Wenn der User nun dieses Formular ausfüllt und abschickt, ist nur das iFrame betroffen, die eigentliche Seite bleibt unberührt.

                    Stattdessen kannst Du von iFrame aus auf die eigentliche Seite zugreifen (parent) und nach Abschicken des Upload-Formulars z.B. eine Grafik mit Progress-Bar über das iFrame legen.

                    1. Zum Prinzip:

                      Du bettest eine (PHP-)Seite (uploadseite) in ein iFrame auf deiner eigentlichen Seite ein. Diese uploadseite enthält ein komplettes Formular zum Fileupload.

                      Viel zu kompliziert!

                      Einfach das Formular in der eigentlichen Seite haben. Außerdem noch ein leeres, kleines IFrame mit in die Seite packen. Das <form> hat als Target das IFrame.

                      Keinerlei Javascript-Schnickschnack im Formular, einfach simples Submit.

                      Im IFrame antwortet der Server dann mit einer kompletten HTML-Seite. Die kann onload im parent-Fenster (also der Seite mit dem Formular) Aktionen ausführen.

                      Oder das IFrame ist einfach so platziert und groß, dass als HTML-Seite einfach nur ein schlichtes "Upload OK" als Text oder Grafik erscheint.

                      Stattdessen kannst Du von iFrame aus auf die eigentliche Seite zugreifen (parent) und nach Abschicken des Upload-Formulars z.B. eine Grafik mit Progress-Bar über das iFrame legen.

                      Kein Progress-Bar.

                      1. Einfach das Formular in der eigentlichen Seite haben. Außerdem noch ein leeres, kleines IFrame mit in die Seite packen. Das <form> hat als Target das IFrame.

                        Keinerlei Javascript-Schnickschnack im Formular, einfach simples Submit.

                        Im IFrame antwortet der Server dann mit einer kompletten HTML-Seite. Die kann onload im parent-Fenster (also der Seite mit dem Formular) Aktionen ausführen.

                        Super, noch bessere Lösung. Danke!!

                      2. Stimmt, das ist noch besser.

                      3. Hallo,

                        Im IFrame antwortet der Server dann mit einer kompletten HTML-Seite. Die kann onload im parent-Fenster (also der Seite mit dem Formular) Aktionen ausführen.

                        Die Same Origin Policy wird das verhindern.

                        Mathias

                        1. hi,

                          Im IFrame antwortet der Server dann mit einer kompletten HTML-Seite. Die kann onload im parent-Fenster (also der Seite mit dem Formular) Aktionen ausführen.

                          Die Same Origin Policy wird das verhindern.

                          Wieso? Es war doch nirgends von zwei unterschiedlichen Domains die Rede?
                          Aus einem Iframe heraus auf das enthaltende Fenster zuzugreifen, sollte das etwa nach dem Wechsel der Ressource im Iframe nicht mehr gehen?

                          gruß,
                          wahsaga

                          --
                          /voodoo.css:
                          #GeorgeWBush { position:absolute; bottom:-6ft; }
                          1. Hallo,

                            Die Same Origin Policy wird das verhindern.

                            Wieso? Es war doch nirgends von zwei unterschiedlichen Domains die Rede?

                            Ich hatte anscheinend (miss)verstanden, dass das eine Dokument auf dem localhost liegen soll.

                            So verstehe ich allerdings weder die Frage noch den Sinn der Antworten. Aber gut...

                            Mathias

                    2. Thanks. Somit ist alles klar!!

                  2. @struppi:

                    Den hast du doch bereits bekommen?
                    Was hast du daran nicht verstanden?

                    Ganz EINFACH: WIE SOLL / KANN ICH DAS AUF EINFACHE ART UMSETZEN??? Was ist da so schwer zu verstehen?

                    Ein iframe erzeugen?
                    mit document.createElement

                    Das Formular an das iFrame senden?
                    mit target

                    Mich interessiert nur eine möglichst einfache Variante, die innerhalb kürzester Zeit implementierbar ist.

                    Die wurde dir schon mehrfach genannt, möchtest du sie jetzt von uns geschrieben bekommen?

                    @wahsaga:

                    Hast du doch bereits bekommen - vielleicht nur noch nicht verstanden?

                    Endlich mal einer, der den Nagel auf den Kopf trifft

                    Was hindert dich daran einfach nachzufragen, anstatt nachzutreten und den Beleidigten zu spielen? Stolz?

                    @marc:

                    Man kann den upload natürlich in ein iFrame verlagern. Das ist _nicht_ ajax.
                    Warum hast Du nicht so weit gedacht?

                    Bin halt nicht so ein Freak hinsichtlich JavaScript wie andere hier im Forum (auch das soll es geben, man glaubt es kaum).

                    die Lösung kannst du sogar völlig ohne JS umsetzen.

                    Struppi.

                    --
                    Javascript ist toll (Perl auch!)
              2. hi,

                Ein bisschen (Weiter-)Denken erwart ich mir eigentlich von den Spezialisten hier schon!

                Das erwarte ich eigentlich schon von jemandem, der an einer solchen Aufgabe arbeitet.

                Gibt es hier denn wirklich niemanden, der anstatt immer gleich 'unmöglich' und 'nicht machbar' zu schreien

                Mi AJAX ist es unmöglich und nicht machbar.

                konstruktive Lösungsansätze von sich gibt?

                Hast du doch bereits bekommen - vielleicht nur noch nicht verstanden?

                gruß,
                wahsaga

                --
                /voodoo.css:
                #GeorgeWBush { position:absolute; bottom:-6ft; }
              3. Nochmal zum Mitschreiben:

                Datei-Upload per _AJAX_ ist unmöglich. Man kann per Javascript noch nicht mal ein input-Feld vom Typ "file" ausfüllen.

                Man kann den upload natürlich in ein iFrame verlagern. Das ist _nicht_ ajax.

                Warum hast Du nicht so weit gedacht?

  2. echo $begrüßung;

    <input type='button' onclick="document.upload_form.bereich_auswertung.value='...'; readSendForm(document.upload_form); return document.returnValue; this.form.submit()"
    Es scheint, als wäre der 'this.form.submit()'-Aufruf komplett wirkungslos.

    Richtig, denn schon beim davor stehenden return wird das onclick verlassen.

    echo "$verabschiedung $name";