Daten mit POST aus einem Script heraus versenden
Hansi (der Dankbare)
- perl
Hallo,
Dies ist kein echtes Problem, so daß ich mir jetzt das Leben nehmen möchte. Ich suche hier eigentlich nur eine andere (feinere) Methode.
Und zwar, der Anwender füllt ein Formular aus. Die Daten werden mit POST an ein Perl-Script übergeben. (Unter den Daten ist auch ein Textfeld, das die Zeichenlänge von 255 Zeichen sprengen kann, weshalb die Methode Get ausfällt)
Die Daten werden aufbereitet, und für jede Übermittlung wird eine neue Datei angelegt in der die Daten gespeichert werden.
Wenn das erledigt ist, wird/soll eine Bestätigungsseite angezeigt. (Im Moment eine ganz normale Seite "Danke für Ihre Mitteilung") Die Seite liegt fertig auf dem Server und das Script sagt einfach print "location: http://antwort.....";
So und jetzt kommt's:
Ich möchte in der Bestätigungsseite die Daten wiedergeben.
ABER!!!!!
Ich möchte die Ausgabe nicht über den print-Befehl an den Browser schicken. Ich möchte die Seite nicht als Datei auf dem Server zwischenspeichern und dann umleiten.
Die im Moment verwendete Lösung ist ein Script, dem ich die Daten ganz normal übergebe und dieses über print "location: "result.cgi?titel=$titel&url=$url&text=$text";
Dies schaut häßlich aus, und bei einem etwas längeren Text werden nicht mehr alle Daten übergeben.
Und nun die Frage die mich interessiert:
Gibt es eine Möglichkeit, daß ich den Aufruf eines anderen Scripts so simulieren kann, daß es für das aufgerufene Script die Methode POST ist und die Daten auch so ausgewertet werden?
Gespannt auf euere Antworten, sage ich jetzt schon mal Danke!
Gruß Hansi
Hi,
Wenn das erledigt ist, wird/soll eine Bestätigungsseite angezeigt. (Im Moment eine ganz normale Seite "Danke für Ihre Mitteilung") Die Seite liegt fertig auf dem Server und das Script sagt einfach print "location: http://antwort.....";
lies die Seite mit open, <HANDLER> und close ein, printe sie direkt nach STDOUT, gehe nicht über Location und ziehe keine 4000 GETs ein ;-)
print "Content-type: text/html\n\n";
open(READ, $datei);
while(<READ>) {
# hier wird der Code verändert, z.B. durch:
s/<!--var1-->/$var1/g;
# und anschließend ausgegeben:
print;
}
close(READ);
Gibt es eine Möglichkeit, daß ich den Aufruf eines anderen Scripts so simulieren kann, daß es für das aufgerufene Script die Methode POST ist und die Daten auch so ausgewertet werden?
Ja, mit LWP::UserAgent mindestens, vielleicht sogar mit LWP::Simple (hab ich noch nicht geprüft); siehe die dazugehörige Doku. Ich bezweifele aber, daß das hier sinnvoll ist; im Zweifelsfall kostet es nur Zeit und Systemressourcen - sowohl auf dem Server als auch beim Benutzer.
Cheatah
Hallo,
Danke erst mal für Deine Antwort.
Wenn das erledigt ist, wird/soll eine Bestätigungsseite angezeigt. (Im Moment eine ganz normale Seite "Danke für Ihre Mitteilung") Die Seite liegt fertig auf dem Server und das Script sagt einfach print "location: http://antwort.....";
lies die Seite mit open, <HANDLER> und close ein, printe sie direkt nach STDOUT, gehe nicht über Location und ziehe keine 4000 GETs ein ;-)
Wer verkauft mir eine Gefängnisfreikarte?
print "Content-type: text/html\n\n";
open(READ, $datei);
while(<READ>) {
# hier wird der Code verändert, z.B. durch:
s/<!--var1-->/$var1/g;
# und anschließend ausgegeben:
print;
}
close(READ);
Das ist das was ich vermeiden wollte.
Ja, mit LWP::UserAgent mindestens, vielleicht sogar mit LWP::Simple
Ist auch nicht die Lösung (wie geht eigentlich das Smile für schlechtes Gewissen).
Ich versuche es nochmal andersrum.
Ein Script wird durchein POST von einem Formular aufgerufen. Dieses Script verarbeitet die übergebenen Daten und speichert diese ab. Zum Schluß soll die Antwortseite angezeigt werden.
Für diese Antwortseite habe ich zwei Möglichkeiten:
1. Ich lasse auf diese Seite mit Print location:http:// umleiten. Dan hat das Script nichts mehr mit dieser Seite zu tun und der Anwender kann soviel Refreshs durchführen wie ermöchte, es bleibt die Antwortseite.
2. Ich lasse die Antwortseite vom Script (wie oben) erzeugen und ausgeben. Wenn jetzt der Anwender einen Refresh durchführt, dann wird das Script nochmal durchgeführt und im Zweifelsfalle werden die Dateien manipuliert oder die Daten verfälscht. (Bei mir wurde mit jedem Refresh eine neue Datei erzeugt.)
Damit dies nicht passiert, sollte es die Möglichkeit geben, von einem Script aus, sozusagen ein Forumular abzuschicken. Diese Daten werden von einem anderen Script insofern abgearbeitet, daß es diese Daten (wie oben) nur darstellt.
Diese Möglichkeit könnte sehr viel Arbeit ersparen, da das Ausgabescript global programmiert werden könnte und viele Abfragen in der normalen Abarbeitung entfallen könnten.
Ist das nun so möglich? und wenn ja wie kann man die Geschichte angehen?
Gruß Hansi
Hi,
nachdem Du sämtliche "sauberen" Lösungen ablehnst ;-) fällt mir nur noch folgendes ein:
Speichere die Daten in einer temporären Datei, die im Namen z.B. die IP-Adresse enthält. Dann leitest Du an ein Script weiter, welches seinerseits anhand der IP die Datei erkennt, die Daten einliest und die Ausgabeseite generiert. Wie Du dabei mit doppelten IP-Adressen vorgehst, überlasse ich Dir *g*
Eine Möglichkeit, Location: mit POST zu verknüpfen (bzw. etwas alternatives dazu) ist mir nicht bekannt, und erscheint mir aufgrund meines Verständnisses der Dinge auch unmöglich.
Cheatah
Hallo,
nachdem Du sämtliche "sauberen" Lösungen ablehnst ;-)
Oh, bitte nicht falsch verstehen. Ich lehne diese Möglichkeiten nicht ab. Ich benutze diese Dinge in fast jedem Skript. Ich sehe indem was ich suche eine Neuerung, zumindest für meine Kenntnisse.
Denn wäre es nicht super, ein Script zu haben, dem ich meine ganzen Daten rüberschaufle (ohne Begrenzungen) und dieses dan anhand einer Vorlage dann die Seite die ich wünsche generiert. Die Adresszeile ist sauber also nicht endlos mit irgendwelchen Parametern gefüllt. Ein Refresh muß im ursprünglichen Script nicht mehr berücksichtigt werden und diese ganzen print-Anweisungen in den anderen Scripts könnten entfallen bzw. durch krüzeren Code ersetzt werden.
Speichere die Daten in einer temporären Datei, die im Namen z.B. die IP-Adresse enthält....
Diese Möglichkeit habe ich auch schon überlegt. Und da im konkreten Fall die Daten ja in einer Datei abgespeichert werden, habe ich es nun auch so ähnlich umgesetzt. Das gleiche Script wird mit einem weiteren Parameter nämlich dem Dateinamen ohne Pfad und Erweiterung übergeben. Bei diesem Aufruf überprüft das Script nun nicht die Eingaben sindern liest die Datei einfach aus und gibt diese nun als Antwortseite aus.
Eine Möglichkeit, Location: mit POST zu verknüpfen (bzw. etwas alternatives dazu) ist mir nicht bekannt, und erscheint mir aufgrund meines Verständnisses der Dinge auch unmöglich.
Mir erschien es nachdem was ich bisher weiß auch nicht möglich, ABER es ist nun schon so oft passiert, daß ich bei der Suche nach irgendwelchen Lösungen auf einmal Dinge, die ich eigentlichschon als nicht machbar abgehakt hatte, auf einmal doch möglich waren.
Deshalb noch einmal wer kennt eine Lösung.
Auf jeden Fall recht herzlichen Dank für Deine Antwort, Cheatah
Gruß Hansi
Das ist das was ich vermeiden wollte.
Ja, mit LWP::UserAgent mindestens, vielleicht sogar mit LWP::Simple
Keine Lösung, nur eine Vertiefung der Quelle:
Im ActivePerl-Handbuch gibt es ein Dokument namens lwpcook (libwww-perl cookbook), da sind typische Anwendungsbeispiele zu WWW-artigen Tasks mit Perl aufgelistet (beispielsweise auch LWP:Simple und get() ).
Dort gibt es folgenden Abschnitt:
POST
There is no simple procedural interface for posting data to a WWW server. You must use the object oriented interface for this.
The most common POST operation is to access a WWW form application:
use LWP::UserAgent;
$ua = new LWP::UserAgent;
my $req = new HTTP::Request 'POST','http://www.perl.com/cgi-bin/BugGlimpse';
$req->content_type('application/x-www-form-urlencoded');
$req->content('match=www&errors=0');
my $res = $ua->request($req);
print $res->as_string;
Wenn Du auf diese Weise Deine kompletten Form-Daten an das Skript zur Ausgabe der Bestätigung weiterleiten kannst, hast Du gewonnen.
Lies Dich mal in LWP:UserAgent ein ...
Hallo,
Wenn Du auf diese Weise Deine kompletten Form-Daten an das Skript zur Ausgabe der Bestätigung weiterleiten kannst, hast Du gewonnen.
Dein Vorschlag löst ein Problem, auf das ich später gestoßen wäre. woher hast du gewußt, daß ich sowas noch brauchen werde? ;-) Man kann das Teil sehr gut für einen Submitservice, wo auch längere Beschreibungen übergeben werden, verwenden. Ich bin bei der Durchsicht der Beispiele und Dokumentation zu libwww auch wieder auf einige Dinge gestoßen, die ich mir eigentlich mal näher anscheuen wollte, aber dann doch wieder vergessen habe. (Altzheimer läßt grüßen) Danke für die Anregung.
In einem gewissen Sinn ist Deine Antwort ja die Antwort auf meine Frage, nur bleibt die Verantwortung weiterhin beim aufrufenden Skript. Und genau das wollte ich umgehen. Eine andere Umschreibung von dem was ich suche wäre ein Redirect mit POST.
Hier mal eine Phantasie:
print "location: POST, http://www..., $Parameter";
Lies Dich mal in LWP:UserAgent ein ...
Habe ich gemacht (Naja zumindest überflogen). Hier überigens ein funktionierendes Beispiel.
#!/usr/bin/perl
use LWP::UserAgent;
$ua = new LWP::UserAgent;
$ua->agent("Mein UserAgent/0.1 " . $ua->agent);
my $req = new HTTP::Request 'POST','http://www.counter-service.de/cgi-bin/formmail.cgi';
$req->content_type('application/x-www-form-urlencoded');
$req->content('re_email=webmaster@timesoft.org&user=timesoft&_ok_url_=http://www.timesoft.org/forms/comment/danke.shtml&r_Kommentar=Hallo und wie gehts');
my $res = $ua->request($req);
print "Content-type: text/html\n\n";
print $res->as_string;
Und das steht dann im Logfile von counter-service
tsnet.timesoft - - [13/Aug/1999:21:05:17 +0200] "POST /cgi-bin/formmail.cgi HTTP/1.0" 200 938 "-" "Mein UserAgent/0.1 libwww-perl/5.44" 1 www.counter-service.de
Das steht im Logfile von timesoft.
timesoft.org - - [13/Aug/1999:21:05:17 +0200] "GET /forms/comment/danke.shtml HTTP/1.0" 200 928
Ich hoffe das ist nicht zu verwirrend 8-{}
Gruß Hansi