Ankündigung

Einklappen
Keine Ankündigung bisher.

Location-Header sofort an Client senden

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Location-Header sofort an Client senden

    Hallo.

    Komische Geschichte:
    PHP-Code:
    <?php
    header
    ('Location: anywhere');
    // echo '.';
    flush();
    sleep(10);
    ?>
    Dieses Skript sendet den Location-Header erst nach seinem kleinen Schläfchen an den Client.

    Wenn ich jedoch nach dem header()-Befehl eine Ausgabe (echo 'irgendwas') mache, dann geschieht der Redirect direkt nach dem flush().

    Kennt ihr einen Weg, wie ich die Header abgeschickt bekomme, ohne das Skript zu beenden oder eben so eine sinnlose Ausgabe vor flush() zu setzen?

    Basti


  • #2
    Eine Antwort, die dich zufriedenstellt habe ich nicht , aber ich habe eine Frage dazu.
    Wenn du den header() absendest ... warum soll das Script dann weiterlaufen?
    privater Blog

    Kommentar


    • #3
      Kennt ihr einen Weg, wie ich die Header abgeschickt bekomme, ohne das Skript zu beenden
      macht definitiv keinen sinn und geht auch nicht ...

      header werden mit php erst genau vor dem ersten 'body'-byte geschickt.
      PHP-Code:
      header('Location: bla');
      exit; 
      ist damit der kürzeste weg, den header sicher und sofort zu verschicken.

      mit
      PHP-Code:
      header('Location: bla');
      // some code ...
      header('Location: blu');
      exit; 
      landet der client übrigens bei 'blu', gellens? ...

      es macht also überhaupt keinen sinn, das skript nach einem Location-header _nicht_ zu beenden, es würde den code nur fehlerträchtig machen.
      logging, debugging etc. sollte vorher stattfinden. der location-header ist damit genau die vorletzte aktion, die du machen solltest.

      und zum flush() --- hast du die anmerkungen zum output-buffering angeschaut?
      http://us2.php.net/manual/en/function.header.php


      grüße
      axo

      Kommentar


      • #4
        Zitat von Ben
        Wenn du den header() absendest ... warum soll das Script
        dann weiterlaufen?
        Garbage Collection, Synchronisierung mit entfernten Server ... denk dir
        was aus. Ich denke da an ein System, bei dem bei praktisch jedem
        Request ein 302er gesendet wird und da könnte man sich den Part danach
        mit Wartungsarbeiten vollpacken, anstatt dem Benutzer das Gefühl zu
        geben, eine Seite sei noch nicht fertig geladen, obwohl ja schon alles
        übertragen wurde (was passiert, wenn du nach einer "normalen" Ausgabe
        noch weiterrechnest).

        Zitat von axo
        es macht also überhaupt keinen sinn, das skript nach
        einem Location-header _nicht_ zu beenden, es würde den code nur
        fehlerträchtig machen.
        Dem kann ich nicht zustimmen. Natürlich kann man so unmöglich
        programmieren, aber wenn das Teil fertig ist, lässt du ja ohnehin keine
        Fehler auf die Bildschirme der Kunden und potentiellen Angeifer prasseln.
        Also was soll das? Und was hat diese Einschränkung mit dem Sinn einer
        slchen Vorgehensweise zu tun?

        und zum flush() --- hast du die anmerkungen zum output-buffering angeschaut?
        http://us2.php.net/manual/en/function.header.php
        Welche Anmerkung meinst du?

        Basti

        Kommentar


        • #5
          Ich mache nach header("Location: ..") auch immer ein exit und hatte noch nie Probleme mit der Weiterleitung.

          Kommentar


          • #6
            Zitat von Zergling
            Ich mache nach header("Location: ..") auch immer ein exit
            und hatte noch nie Probleme mit der Weiterleitung.
            Das ist ja auch nicht der Punkt. Meine Frage wäre, ob es einen Weg gibt, PHP
            mitzuteilen, dass nun keine Header mehr folgen, außer eben durch eine
            Beedigung des Skriptes oder das Senden von "body-Bytes".

            Basti

            Kommentar


            • #7
              Re: Location-Header sofort an Client senden

              Zitat von Basti
              Kennt ihr einen Weg, wie ich die Header abgeschickt bekomme, ohne das Skript zu beenden oder eben so eine sinnlose Ausgabe vor flush() zu setzen?
              Die Frage ist doch wozu? Du willst eine Weiterleitung aber das Skript nicht beenden, das ergibt irgendwie keinen Sinn. Wenn du noch ne Aktion vor der Weiterleitung ausführen willst, dann schreibs auch im Code vor die Weiterleitung?

              Das weißt du ja denke ich mal auch, aber wüßt gern was du dann überhaupt vor hast

              Kommentar


              • #8
                Hi.

                Okay, ich breite mich mal aus:

                Ich will keine Aktion vor der Weiteleitung durchführen, sondern danach. In einem System,
                an dem ich gerade dran bin, gibt es zwei Arten von Requests: Anfragen nach Seiten (page=home)
                und Befehle, die übergeben werden (cmd=deluser&user=42 bzw. als ID, hinter der eine
                Callback-Funktion steht).

                Kommt eine action-Anfrage, so wird die Seite zusammengebaut, in die Session gepackt (unter
                dem Titel der auszugebenden Seite und vielleicht mit Verfallsdatum) und eine Umleitung auf den
                entsprechenden Page-Request geschickt. Kommt also ein Page-Request, so wird in der Session
                geschaut, ob die Seite dort noch aktuell liegt und ausgespuckt.

                Das hat einfach den Vorteil von einem URI, der auch dem angezeigten Inhalt entspricht, obwohl die
                Schaltflächen/Links, die mit Callback-Funktionen hinterlegt sind eine Kombination aus Session-ID
                und der ID des Konkreten Callback-Aufrufs enthält. Und natürlich wird ein zweites Ausführen einer
                Aktion durch einen Reload verhindert.

                Beispiel:
                Benutzer "Admin" möchte einen Benutezr löschen und lässt sich dazu eine Tabelle mit Benutzern
                anzeigen. Diese Seite "usertable" enthält pro Zeile einen Link "delete". Beim Erstellen dieser Seite
                wurden im Template diese Links erzeugt, indem eine Methode eines Widget-Objekt mit den
                Parametern module=usermng, cmd=delete, user=<ID_des_Benutzers > aufgerufen wurde. Diese
                hat das jeweilige Commando mit einer ID (md5(uniquid())) versehen, in eine Tabelle in die Session
                gepackt und aus dieser ID und der Session-ID den Link zusammengebacken und zurückgegeben.

                Klickt also der Besucher nun auf einen sochen "delete"-Link, sieht der Request z.B. so aus:
                ?cmd=45ab379cd53f14ef2a6bc692cae36f&sid=826abfe0ab fe3428fb3e4ad387ed241
                Dieser wird dann also Übersetzt nach Module=User, cmd=delete, user-ID=42. Je nach Ergebnis
                dieser Anfrage wird dann z.B. entschieden, die Tabelle erneut anzuzeigen (jetzt ohne den
                gelöschten Benutzer), oder eine Sicherheitsabfrage ('Wirklich löschen?') oder sonstwas
                anzuzeigen. Die Seite wird zusammengebastelt und unter dem Namen der Seite ('usertable',
                'confirm', ...) in die Session gepackt (ggf. noch mit einer ID versehen, falls eine Seite diesen Typs
                schon in der Tabelle steht).

                Daraufhin gibt es einen Redirect z.B. nach example.com/confirm oder auch example.com/confirm/2
                und durch diesen Request wird die bereits fertige Seite aus der Session ausgespuckt.

                Und nun wäre es ja denkbar, nach diesem Redirect von dem weiterleitenden Skript noch Jobs
                erleigen zu lassen, für die man sonst Cronjobs bemühen würde, die jedoch in keiner Verbindung
                zu der gerade angefragten Aktion/Seite etc. stehen, wie eben z.B. aufzuräumen, Mails
                rauszuschicken, überarbeitete Dokumentenversionen zu archivieren etc. Eben alles, das weder
                punktgenau, noch vor dem Erstellen einer Seite erledigt werden muss.

                Das ist eigentlich alles. Und ich halte es weder für sinnlos, noch für problematisch, denn es
                unterscheidet sich von einem "gewöhlichen" Cronjob lediglich durch die Ungewissheit des
                Zeitpunktes der Ausführung und der Gesamtlaufzeit, die diesen Jobs zur Verfügung steht. Beides
                Punkte, die man natürlich beachten muss.

                Das einzige Problem, das ich sehe ist die Möglichkeit, dass ein Client mit dem Ausführen des
                Redirect warten könnte, bis die Anfrage komplett beantwortet wurde, also eben erst nach den
                "Cronjobs". Das wäre letztlch auszuprobieren.

                Basti

                Kommentar

                Lädt...
                X