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

  • Basti
    hat ein Thema erstellt Location-Header sofort an Client senden.

    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

  • Basti
    antwortet
    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

    Einen Kommentar schreiben:


  • Zergling-new
    antwortet
    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

    Einen Kommentar schreiben:


  • Basti
    antwortet
    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

    Einen Kommentar schreiben:


  • Zergling-new
    antwortet
    Ich mache nach header("Location: ..") auch immer ein exit und hatte noch nie Probleme mit der Weiterleitung.

    Einen Kommentar schreiben:


  • Basti
    antwortet
    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

    Einen Kommentar schreiben:


  • axo
    antwortet
    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

    Einen Kommentar schreiben:


  • imported_Ben
    antwortet
    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?

    Einen Kommentar schreiben:

Lädt...
X