hawkmaster: Auto Upload mit AJAX & PHP?

Hallo zusammen,
momentan habe ich eine Upload Möglichkeit in einem Formular. Der User klickt auf "durchsuchen", wählt die Datei aus und klickt dann auf einen "Upload" submit button. Soweit so gut.

Ich überlege nun, ob man dies vereinfachen kann. Also ohne zusätzlichen Submit Klick. Die Datei soll gleich nach der Auswahl aus dem Dateisystem hochgeladen werden.
Folgendes habe ich bis jetzt hinbekommen:

Das Input Type= file
------------------------------------------
 <input type="file" name="upload_file" id="upload_file" onchange="makeAutoUpload(this.value,<?php echo $UserID; ?>);" />

Die Funktion "makeAutoUpload:

  
function makeAutoUpload(UploadFile,UserID){  
xmlhttp=GetXmlHttpObject();  
if (xmlhttp==null)  
  {  
  alert ("Browser does not support HTTP Request");  
  return;  
  }  
var url="../include/autoupload.php";  
url=url+"&UserID="+UserID;  
url=url+"&UploadFile="+UploadFile;  
//xmlhttp.onreadystatechange=UploadStateChanged;  
xmlhttp.open("GET",url,true);  
xmlhttp.send(null);  
}  

Die PHP Seite autoupload.php für den eigentlichen Upload

  
$UserID = $_GET['UserID'];  
$UploadFile = $_GET['UploadFile'];  
....  
//echo "die UserID ist $UserID <br>";  
echo "das upload file ist $UploadFile <br>";  
	$file_name = $_FILES['print_file']['name'];  
	$file_size = $_FILES['print_file']['size'];  
	$file = $_FILES['print_file']['tmp_name'];  
...  
if(copy($file, "$userupload/$file_name")){  
}  

Mein Problem ist momentan das ich nicht wie früher (mit dem Submit Button) auf $_FILES[ zugreifen kann, weil ja das Absenden via Post fehlt.
Daher hatte ich versucht mit "this.value" bzw. der Übergabe mit $_GET['UploadFile'] die Datei mitzugeben. Das klappt soweit für den Dateinamen. Der ganze Pfad wird aber nicht übertragen, obwohl es eigentlich im Input Type=File so angezeigt wird.

Kann mir jemand weiterhelfen? Ist sowas überhaupt möglich?

vielen Dank und viele Grüße
hawk

  1. Hi,

    momentan habe ich eine Upload Möglichkeit in einem Formular. Der User klickt auf "durchsuchen", wählt die Datei aus und klickt dann auf einen "Upload" submit button. Soweit so gut.
    Ich überlege nun, ob man dies vereinfachen kann. Also ohne zusätzlichen Submit Klick. Die Datei soll gleich nach der Auswahl aus dem Dateisystem hochgeladen werden.

    ich hätte behauptet, das sei nicht möglich; ich war der Meinung, der onchange-Event würde auf einem File-Upload-Feld nicht ausgelöst. Aber selbst wenn, halte ich es nicht für eine gute Idee. Was ist, wenn ich mich bei der Dateiauswahl vertan habe? Dann lade ich "aus Versehen" den letzten Brief an meinen Anwalt hoch. Hmm.

    function makeAutoUpload(UploadFile,UserID){

    xmlhttp=GetXmlHttpObject();
    if (xmlhttp==null)
      {
      alert ("Browser does not support HTTP Request");
      return;
      }
    var url="../include/autoupload.php";
    url=url+"&UserID="+UserID;
    url=url+"&UploadFile="+UploadFile;
    //xmlhttp.onreadystatechange=UploadStateChanged;
    xmlhttp.open("GET",url,true);
    xmlhttp.send(null);
    }

      
    Warum so aufwendig? Warum nicht einfach die submit-Methode des Formulars aufrufen?  
      
    
    > Mein Problem ist momentan das ich nicht wie früher (mit dem Submit Button) auf $\_FILES[ zugreifen kann, weil ja das Absenden via Post fehlt.  
    > Daher hatte ich versucht mit "this.value" bzw. der Übergabe mit $\_GET['UploadFile'] die Datei mitzugeben. Das klappt soweit für den Dateinamen. Der ganze Pfad wird aber nicht übertragen, obwohl es eigentlich im Input Type=File so angezeigt wird.  
      
    Das ist AFAIK sogar je nach Browser unterschiedlich. Aber egal wie, du kriegst auch diese Weise nur den Namen, aber keinen Datei-Upload, d.h. der Dateiinhalt wird nicht übertragen. Den bekommst du nur, wenn du wirklich das Formular absendest. Und von diesem automatischen Absenden einschließlich Upload rate ich dringend ab.  
      
    So long,  
     Martin  
    
    -- 
    [Gott hilft niemandem](http://forum.de.selfhtml.org/?t=134084&m=869527), er erfreut sich nur an unseren Leiden.  
      (Ashura)  
      
    Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
    
    1. Hallo zusammen,

      Danke ChrisB und MArtin für eure Ratschläge. Ich habe mir sowas fast schon gedacht. Alles was ich bisher gefunden habe war auch furchtbar aufwendig und fast immer mit Iframes gemacht.
      Ich denke ich lasse es dann einfach wie ich es bisher hatte, mit dem Submit Button.
      Ich wollte eigentlich nur die "Usability" verbessern und einen Klick einsparen :-)

      vielen Dank und viele Grüße
      hawk

      1. Hallihallo!

        Ich denke ich lasse es dann einfach wie ich es bisher hatte, mit dem Submit Button.

        Das ist auf jeden Fall die bessere Wahl, und trotzdem möchte ich der Vollständigkeit halber darauf hinweisen, dass man tatsächlich das onchange- event benutzen KÖNNTE:

          
        <form name="formular" id="myform" method="POST" action="....." ....>  
            <input type="file" name="myfile" onchange="senden();">  
        </form>  
        
        

        mit der Funktion senden():

          
        function senden() {  
            // evtl ein paar Clientseitige Checks für den Dateinamen oder so...  
            document.getElementById("myform").submit();  
        }  
        
        

        In einem meiner (Intranet-) Projekte, in dem die Nutzer einen einfachen Multi- File- Upload haben wollten, habe ich auf diese Weise nach jeder erfolgten Dateiauswahl ein komplettes zusätzliches Formular ins DOM eingehängt, nebst einem für dieses Formular zuständigen target- iframe.
        Per Klick auf den einzigen Submit- Button wird dann ein Formular nach dem anderen abgesendet, und in den iframes erscheinen nacheinander dann die Thumbnails zu den hochgeladenen Dateien.
        Mit Browsern, die Drag und Drop auf das Formularfeld unterstützen, macht so das Hochladen von vielen Dateien fast schon Spaß :)

        Was ich damit unterm Strich sagen will: So Einiges ist möglich, wenn auch nur in Ausnahmesituationen sinnvoll.

        Beste Grüsse,
            Tobias Hahner

        PS: Der Code oben ist quick and dirty, Syntax- und Schreibfehler nicht ausgeschlossen

  2. Hi,

    momentan habe ich eine Upload Möglichkeit in einem Formular. Der User klickt auf "durchsuchen", wählt die Datei aus und klickt dann auf einen "Upload" submit button. Soweit so gut.

    Ich überlege nun, ob man dies vereinfachen kann. Also ohne zusätzlichen Submit Klick. Die Datei soll gleich nach der Auswahl aus dem Dateisystem hochgeladen werden.

    url=url+"&UploadFile="+UploadFile;

    Zumindest so geht es, wie Martin schon sagte, nicht.

    Mein Problem ist momentan das ich nicht wie früher (mit dem Submit Button) auf $_FILES[ zugreifen kann, weil ja das Absenden via Post fehlt.

    Schlau erkannt.

    Daher hatte ich versucht mit "this.value" bzw. der Übergabe mit $_GET['UploadFile'] die Datei mitzugeben. Das klappt soweit für den Dateinamen. Der ganze Pfad wird aber nicht übertragen, obwohl es eigentlich im Input Type=File so angezeigt wird.

    Ja, schon da enden deine Möglichkeiten mit bisher gängigem HTML und JavaScript.
    Ob der Pfad übertragen wird, ob du per JS Zugriff darauf hast - das liegt hauptsächlich an den Sicherheitseinstellungen des Clients.

    Ist sowas überhaupt möglich?

    Echte File-Uploads per AJAX werden erst mit der mit HTML5 eingeführten File API möglich.
    Siehe bspw. https://developer.mozilla.org/en/Using_files_from_web_applications

    So lange das nicht browserübergreifend implementiert ist, bist du mit der herkömmlichen Methode - echtes Formular wirklich absenden - besser bedient.
    Ob es sich jetzt schon lohnt, zweigleisig zu Programmieren, um beides abzudecken, bezweifle ich.

    MfG ChrisB

    --
    RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
  3. hi,

    Ich überlege nun, ob man dies vereinfachen kann. Also ohne zusätzlichen Submit Klick. Die Datei soll gleich nach der Auswahl aus dem Dateisystem hochgeladen werden.

    Bei einem Upload werden bytes aus der Datei gelesen, nicht Zeichen. Das DOM scheitert hier schon beim Lesen einer Datei aus dem Dateisystem und spätestens bei der Berechung von Content-Length, dieser header ist bei einem POST erforderlich (Zeichenkette.length liefert 1, wenn sich aus 2 bytes ein Zeichen in "var Zeichenkette" ergibt). Kurzum: Wenn Du es mit DOM Methoden hinkriegst, aus dem Dateisystem eine Datei zu lesen und aus der binary eine Hexmap like %FC%A3%BC.... zu machen, könnte ein Upload auch mit enctype="application/x-www-form-urlencoded", der richtigen content-length für einen POST und sogar mit method="GET" funktionieren (letztere braucht kein Längenangabe).

    Hotti (no reg)