Announcement

Collapse
No announcement yet.

File-Upload ohne Seitenwechsel

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • File-Upload ohne Seitenwechsel

    Hi,

    Ich habe da mal wieder ein Problem, bei dem ich als Anfänger nicht weiterkomme.
    Ich habe zwar schon ein bisschen gegoogelt, aber was ich gefunden habe, läuft immer wieder darauf hinaus, dass eine neue Seite geladen werden muss.

    Also, ich möchte auf einer Platform in einem bestimmten Verzeichnis eine ZIP-Datei hinterlegen, die dann vom System später weiterverarbeitet wird. Hierfür habe ich das HTML Form-Element file gefunden. Die entsprechende Form auf der Webseite dazu sieht so aus:

    [highlight=HTML]
    <form action="classes/http_request/uploadFWZip.php" method="post" enctype="multipart/form-data" name="f">
    <table border="0">
    <tr >
    <td valign="top"><id="FWfilename" input type="file" name="FWZipfile"><br><input id="btnUploadFWZip" type="button" value="<?php print Text::getText($page, 3) ?>" onClick="UploadFWZip()"></td>
    <td valign="top"><input id="btnStartUpgrade" type="button" value="<?php print Text::getText($page, 4)?>" onclick="SendStartFWUpgrade()" disabled = true></td>
    </tr>
    </table>
    </form>
    [/highlight]

    Die zugehörige JavaScript-Funktion so:
    [highlight=JavaScript]
    function UploadFWZip()
    {
    if(document.getElementById(elementId).value.length >0)
    document.f.submit();
    }
    [/highlight]

    Und das php-Skript so:
    [highlight=php]
    <?php
    error_reporting(E_ALL);

    if(isset($_FILES["FWZipfile"]))
    {
    if($_FILES["FWZipfile"]["error"] == UPLOAD_ERR_OK)
    {
    move_uploaded_file($_FILES["FWZipfile"]["tmp_name"], "/tmp/FW.zip");
    echo "OK";
    }
    else
    {
    echo "err: upload error " . $_FILES["FWZipfile"]["error"];
    }
    }
    else
    {
    echo "err: no files present.";
    }
    ?>
    [/highlight]

    Insgesamt klappt das zwar (also die Datei wird übermittelt, entsprechende Prüfungen, dass der User da keinen Mist hochlädt, sind noch einzubauen) und landet auch unter neuem Namen im /tmp-Verzeichnis, aber die Rückgabe wird als neue Seite angezeigt. Stattdessen würde ich nun gerne den Upload als http-Request realisieren, dessen Antwort ("OK" oder Fehlermeldung) dann ausgewertet wird (entweder den StartUpgrade-Button aktivieren bzw. eine Rückmeldung bei Fehler). Mir fehlt aber der Ansatz, das ganze so zu einem http-Request umzustricken, dass ich um das form.submit() herumkomme, dass mir ja eine neue Datei lädt. Also irgendetwas in der Form:
    [highlight=JavaScript]
    function UploadFWZip()
    {
    var xmlhttp;
    if(window.XMLHttpRequest)
    xmlhttp=new XMLHttpRequest;
    else
    xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
    xmlhttp.onreadystatechange=function()
    {
    if(xmlhttp.readyState == 4)
    {
    var result = xmlhttp.responseText;
    if(xmlhttp.status==200)
    {
    if(result =="OK")
    {
    alert("OK");
    document.getElementById("btnStartUpgrade").disable d=false;
    }
    else
    alert("<?php print Text::getText('PAGE_ERROR', 'err6')?>");
    }
    else
    alert("<?php print Text::getText('PAGE_ERROR', 'err6')?>");
    }
    }

    xmlhttp.open("POST", 'classes/http_request/uploadFWZip.php', true);
    xmlhttp.setRequestHeader(????);
    ????
    xmlhttp.send(????);
    }
    [/highlight]

    Da es sich bei dem "Webserver" um einen Server auf einer embedded-Platform handelt, kann ich nicht Ajax-Framework oder ähnliches installieren, bin also auf php und JavaScript angewiesen.

    Und kann man dem Form-Element file irgendwelche Filter mitgeben, dass von vorneherein nur ZIPs ausgewählt werden können?

    Gruß
    Martin

  • #2
    Das geht nicht, außer du realisierst den Upload über AJAX. Wenn ein Request zum Server ausgelöst wurde, muss dieser irgendwas zurückliefern. Ohne einen Request zu Server kann auch nicht der Upload verarbeitet werden. PHP läuft nur auf dem Server
    Christian

    Comment


    • #3
      Sorry Christian, aber irgendwie kann ich Deiner Argumentation nicht folgen:

      Der Upload geht nur mit Request auf dem Server (deshalb muss ich ja einen httpRequest abschicken, und kann das nicht allein mit JavaScript handhaben). Dies benötigt ein PHP-Script auf dem Server (das erwähnte uploadFWZip.php), das die Datei entgegennimmt, kopiert und auf den Request auch was zurückliefert (ein "OK" oder ein "err:..."). Dieses php Script läuft auf dem Server.

      Die von Dir aufgezählten Bedingungen sind also erfüllt, warum es dann nur mit Ajax-Frameworks gehen soll und nicht mit Standard-php-Funktionen, erschließt sich mir nicht. Im Endeffekt geht es ja hauptsächlich darum, von einem Form-Submit() auf einen XMLHttpRequest umzuformen, und wie man dem XMLHttpRequest die Datei, die im file-Element des Forms geladen wurde, als Parameter übergeben kann.

      Um das also nochmal klarzustellen: Es geht nicht darum, dass das Prinzip von Ajax-Anfragen nicht möglich ist (Wenn ich das richtig verstanden habe, ist der HTTP-Request an sich ja auch schon eine AJAX-Anfrage), sondern es können nur die verschiedenen Ajax-Frameworks und deren sogenannten "Standard-Klassen" nicht verwendet werden, und ich bin auf die Standard-PHP-Funtionen beschränkt.

      Comment


      • #4
        Auf dem Client hast du keine "Standard-php-Funktionen". Diese gibt es erst auf dem Server.
        Ein Submit-Button löst einen SYNCHRONEN Request aus. Auf diesen erwartet der Client einen Response (die Antwort und damit einen Seitenaufbau). Mit Ajax kannst du einen ASYNCHRONEN Request auslösen. Der Client wartet hier nicht auf eine Antwort.

        Im Endeffekt geht es ja hauptsächlich darum, von einem Form-Submit()...
        Wozu? Setze einen "normalen" Button in deine Form und auf OnClick wird der Ajaxrequest gesandt. Per Javascript wird das PHP-Script auf dem Server asynchron aufgerufen. Ein Submit ist dann "nicht beteiligt"

        (Wenn ich das richtig verstanden habe, ist der HTTP-Request an sich ja auch schon eine AJAX-Anfrage),
        Nein s.o.

        Ajax-Frameworks und deren sogenannten "Standard-Klassen" nicht verwendet werden, und ich bin auf die Standard-PHP-Funtionen beschränkt.
        Die Ajax-Frameworks haben nie etwas mit PHP oder den auf den Server laufenden Programmen zu tun; außer das sie diese aufrufen. Sie laufen immer clientseitig. Und PHP hat umgekehrt nie etwas mit einem Ajaxrequest zu tun. Außer, dass das Script auf dem Server von diesem aufgerufen wird. Es spielt für das Script keine Rolle, ob es von einem normalen Request oder einem Ajaxrequest aufgerufen wird.


        Hilft bei der Realisierung
        http://jquery.com/

        http://valums.com/ajax-upload/
        Zuletzt editiert von Christian Marquardt; 22.11.2011, 07:58.
        Christian

        Comment


        • #5
          Hallo Martin,

          irgendwie scheinst du die Technologien und Begrifflichkeiten etwas durcheinander zubringen.
          Javascript und damit auch ein Javascript-Framework läuft IMMER auf dem Client und hat mit dem Server überhaupt nichts zu tun. PHP dagegen ist eine serverseitige Scriptsprache und völlig unabhängig vom anfragenden Client.
          Auch hat ein HTTP-Request nichts mit AJAX zu tun. Andersherum wird ein Schuh draus: AJAX ist eine Technologie um mit Javascript asynchrone HTTP-Requests realisieren zu können. AJAX ist also einzig und allein Sache des Client - dem Server ist es völlig egal, aus seiner Sicht beantwortet er einen ganz normalen HTTP-Request!
          File-Upload mit AJAX ist nicht trivial, vor allem wenn du auf vorgefertigte Frameworks verzichten willst. Hier solltest du dir ganz genau anschauen, wie ein File-Upload-Request aussehen muss. Für den Anfang einfacher ist dabei auf alle Fälle der komplette Verzicht auf JS. Was spricht eigentlich gegen die "ganz normale Antwortseite" bei einem synchronen Request per Formular?

          Gruß Falk
          Wenn du denkst du hast alle Bugs gefunden, dann ist das ein Bug in deiner Denksoftware.

          Quellcode ohne ein Mindestmaß an Formatierung sehe ich mir nicht an! Ich leiste keinen Privatsupport per Mail oder PN!

          Comment


          • #6
            Hi Falk,

            ich dachte bisher immer AJAX umfasst sowohl die JavaScript als auch die serverseitige Implementierung (egal, ob das nun von einem CGI oder PHP entgegengenommen wird), gerade weil ich in den meisten Lösungen, die ich so ergoogelt hatte, auch im PHP-Script auf spezielle Klassen verweisenden Code gefunden habe, und dann müssten ja auf dem Server entsprechende JavaScript-Frameworks und gleichermaßen PHP-Bibliotheken installiert sein. Wenn AJAX nur die Seite JavaScript umfasst, dann bestand hier eine Begriffsfehlinterpretation, was es aber dennoch nicht einfacher machen würde, dem Marketing zu erklären, warum ein komplettes Framework mit ausgeliefert (und gewartet) werden muss, das im Standard-WebServer nicht enthalten ist.

            Gegen den Aufbau einer kompletten Antwortseite durch das php-Script spricht hauptsächlich, dass der Upload der Firmware auf das Gerät ein Schritt unter vielen Optionen der Wartungsseite ist, und ich quasi die ganze Seite (die selbst ja auch wieder von einem php-Script aufgebaut wird, und sei es nur zur Sprachspezifischen Textauswahl) von diesem php-Skript zurückgegeben werden müsste, inklusiver aller Einstellungen, die anderen Bereichen der Seite schon vom Benutzer eingestellt wurden oder vom System erfragt werden. Oder ich müsste einen Redirect auf "Erfolgsseite" und "Fehlschlagseite" ausgeben, auf der dann der User den FW-Upgrade auslösen bzw. den Upload erneut probieren kann. Das ist zwar durchaus möglich, aber dann stricke ich von der Benutzerhandhabung her eine Sonderlocke für diese Funktionalität, und sowas würde ich gerne vermeiden, wenn es geht.

            Gruß
            Martin

            Edit: hab nach einem weiteren halben Tag googeln dann doch noch eine Möglichkeit gefunden: mit einem FormData-Objekt. Was genau DA dahintersteht, kann ich zwar nicht sagen, aber es funktioniert.

            [highlight=JavaScript]
            function UploadFWZip()
            {

            if(document.getElementById("FWfilename").value.len gth<=0)
            {
            alert("<?php print Text::getText($page, 6)?>");
            return;
            }
            var fData=new FormData(document.getElementById("FWform"));

            var xmlhttp;
            if(window.XMLHttpRequest)
            xmlhttp=new XMLHttpRequest;
            else
            xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
            xmlhttp.onreadystatechange=function()
            {
            if(xmlhttp.readyState == 4)
            {
            var result = xmlhttp.responseText;
            if(xmlhttp.status==200)
            {
            if(result =="OK")
            {
            alert("OK");
            document.getElementById("btnStartUpgrade").disable d=false;
            }
            else
            alert("<?php print Text::getText('PAGE_ERROR', 'err6')?>");
            }
            else
            alert("<?php print Text::getText('PAGE_ERROR', 'err6')?>");
            }
            };

            xmlhttp.open("POST", 'classes/http_request/uploadFWZip.php', true);
            xmlhttp.send(fData);
            }
            [/highlight]
            Zuletzt editiert von M.Dietz; 22.11.2011, 17:07.

            Comment


            • #7
              Mit Hilfe eines IFrames und etwas Javascript dürfte das möglich sein. Hab sowas selber mal gemacht. Einfach Denken...

              Comment


              • #8
                Dann zeige doch mal den Code....insbesondere den Upload mit Javascript
                Christian

                Comment


                • #9
                  Im grunde ganz einfach....

                  Code:
                  <form ... target="uploadFrame">....</form><iframe name="uploadFrame"></iframe>
                  Nach dem Submit wird dein Form abgeschickt und das Ergebniss im uploadFrame verarbeitet bzw. angezeigt. Über DIV und ausblenden kannste dann auch noch Rückmeldungen an den User geben, damit der dann auch weiß was passiert. Ein wenig JS und CSS und gut is :-)

                  Comment

                  Working...
                  X