![]() |
TidHTTP.Post() - Parameter werden nicht getrennt
Hallo Forum,
wie ich bei einer Suche hier im Forum feststellen musste, existieren schon einige Beiträge zum Thema TidHTTP.Post() und nicht (richtig) ankommende Parameter, allerdings ist mein Fall etwas anders gelagert. Zuerst einmal der Code (der Vollständigkeit wegen etwas länglich, der wichtige Teil ist durch '!!! ... !!!'-Kommentare kenntlich gemacht):
Delphi-Quellcode:
Wie man vielleicht erkennen kann, soll das einen HTTP-Proxy darstellen. Mit dem HTTP-Server aus Indy wird ein Request angenommen, an TidHTTP weitergeleitet und dessen Ergebnis wiederum an den Aufrufer zurückgegeben. (Für GET-Anfragen - hier rausgestrichen - funktioniert das übrigens problemlos.)
procedure Proxy.HTTPServerCommandGet(AThread: TIdPeerThread;
RequestInfo: TIdHTTPRequestInfo; ResponseInfo: TIdHTTPResponseInfo); var i : integer; HTTPClient : TIdHTTP; tmpStringList : TStringList; begin // HTTPClient initialisieren HTTPClient:=TIdHTTP.Create(nil); HTTPClient.HandleRedirects:=true; HTTPClient.ProtocolVersion:=pv1_0; // HTTP-Header manipulieren // ... // POST-Anfragen weitergeben if (RequestInfo.Command='POST') then begin ResponseInfo.ContentStream:=TMemoryStream.Create; tmpStringList:=TStringList.Create; // !!! Hier beginnt das Problem !!! for i:=0 to RequestInfo.Params.Count-1 do begin // Variante 1 tmpStringList.Add(RequestInfo.Params.Strings[i]); // Variante 2 // if (i<RequestInfo.Params.Count-1) then tmpStringList.Add(URLEncode(RequestInfo.Params.Strings[i] + '&')) // else tmpStringList.Add(URLEncode(RequestInfo.Params.Strings[i])); end; HTTPClient.Post('http://' + RequestInfo.Host + RequestInfo.Document, tmpStringList, ResponseInfo.ContentStream); // !!! Hier endet das Problem !!! end; ResponseInfo.ContentType:=HTTPClient.Response.ContentType; ResponseInfo.ContentLength:=length(ResponseInfo.ContentText); ResponseInfo.ResponseNo:=HTTPClient.ResponseCode; ResponseInfo.ServerSoftware:=HTTPClient.Response.Server; ResponseInfo.WriteHeader; ResponseInfo.WriteContent; end; Bei POST-Anfragen gibt es aber folgendes Problem: tmpStringList enthält die Parameter für die POST-Anfrage und hat nach dem Befüllen aus RequestInfo.Params z.B. den folgenden Inhalt: tmpStringList.Strings[0]='nick=Anonym' tmpStringList.Strings[1]='mail=beispiel' tmpStringList.Strings[2]='msg=Inhalt' tmpStringList.Strings[3]='id=camponotus' Das ist soweit auch korrekt. Wenn ich nun aber testweise ein PHP-Skript aufrufe, das lediglich die oben genannten Variablen ausgibt, erhalte ich folgendes Ergebnis: $id= $nick=Anonym mail=beispiel msg=Inhalt id=camponotus $mail= $msg= Offensichtlich werden die einzelnen Parameter also nicht getrennt und der komplette String der ersten Variable zugewiesen. Deswegen habe ich eine zweite, im obigen Code auskommentierte Variante zum Einlesen der Parameter ausprobiert, die an alle Parameter ausser dem letzten ein '&' anhängt. Dann sehen tmpStringList und das Ergebnis des PHP-Skripts so aus: tmpStringList.Strings[0]='nick=Anonym&' tmpStringList.Strings[1]='mail=beispiel&' tmpStringList.Strings[2]='msg=Inhalt&' tmpStringList.Strings[3]='id=camponotus' => $id= $nick=Anonym $mail= $msg= Jetzt werden die Parameter nach dem ersten '&' also einfach ignoriert. Mein Ziel wäre folgende Ausgabe: $nick=Anonym $mail=beispiel $msg=Inhalt $id=camponotus Kann mir jemand sagen, wie ich das erreiche? Offensichtlich stimmt ja etwas mit dem Abgrenzen der Parameter nicht. Mit #13+#10 statt '&' will es aber auch nicht gelingen. Genausowenig hilft die direkte Übergabe von RequestInfo.Params.Strings an Post(). Das PHP-Skript ist übrigens nicht die Fehlerquelle, zumindest funktioniert es ohne den Umweg über den Proxy wie erwartet. Als Entwicklungsumgebung nutze ich Delphi 6 und die mitgelieferte Indy-Version. Vielen Dank im voraus für alle Lösungen bzw. Anregungen. |
Re: TidHTTP.Post() - Parameter werden nicht getrennt
Herzlich Willkommen in der Delphi-PRAXiS, TDKBacke.
Mir fallen an deinem Code zwei Dinge auf. Du setzt die Protokoll-Version explizit auf pv1_0, wo doch die Indy-Macher schreiben, dass Indy selbsttätig einen fallback durchführt, sobald POST verwendet wird und solange keine bessere Methode bekannt ist um mit fehlerhaften HTTP Servern zu kommunizieren. Dann wäre da noch dein FOR loop. Ich denke, dass du den eliminieren kannst:
Delphi-Quellcode:
Ich kann den Code momentan nicht testen, aber auch wenn er dein Problem nicht löst, dann reduziert er wenigstens die lines of code.
// !!! Hier beginnt das Problem !!!
HTTPClient.Post( 'http://' + RequestInfo.Host + RequestInfo.Document, RequestInfo.Params, ResponseInfo.ContentStream ); // !!! Hier endet das Problem !!! Grüße vom marabu |
Re: TidHTTP.Post() - Parameter werden nicht getrennt
@marabu:
Danke für die Begrüßung und die Antwort. Allerdings: Zitat:
Werde mal auf HTTP 1.1 umstellen und sehen, was sich dadurch verändert. Klingt ja recht vielversprechend, wenn da von Entwicklerseite auf Probleme hingewiesen wird. :) |
Re: TidHTTP.Post() - Parameter werden nicht getrennt
Hallo,
deinen vergeblichen Versuch die RequestInfo.Params direkt zu übergeben habe ich in der Fülle deines Beitrages wohl überlesen - tut mir leid. Ich habe mir nun auch einen Proxy (zum Testen) geschrieben, beim IE eingetragen und ein Formular (4 Input Felder) mit POST in Auftrag gegeben. Ich speichere die Request.Params in einem ValueListEditor damit ich mitverfolgen kann, was so an Daten fließt - deshalb die CriticalSection UILock. Intern leite ich den Request auf eine PHP-Seite, die mir mit phpinfo() alle POST Variablen anzeigt. Alles schaut so aus wie du es gerne hättest. Jetzt ist es an dir den Unterschied in der Vorgehensweise zu finden.
Delphi-Quellcode:
Grüße vom marabu
procedure TDemoForm.HTTPServerCommandGet(AThread: TIdPeerThread;
ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo); var client: TIdHTTP; begin UILock.Acquire; try VLE.Strings.Assign(ARequestInfo.Params); finally UILock.Release; end; AResponseInfo.ContentStream := TMemoryStream.Create; client := TIdHTTP.Create(nil); with client do begin Request.Assign(ARequestInfo); HandleRedirects := true; AllowCookies := true; CookieManager := TIdCookieManager.Create(client); end; if ARequestInfo.Command = 'POST' then client.Post( // 'http://' + ARequestInfo.Host + ARequestInfo.Document, 'http://localhost/root/test.php', ARequestInfo.Params, AResponseInfo.ContentStream ) else if ARequestInfo.Command = 'GET' then client.Get( 'http://' + ARequestInfo.Host + ARequestInfo.Document, AResponseInfo.ContentStream ) else begin ShowMessage(ARequestInfo.Command); Exit; end; AResponseInfo.ContentType := client.Response.ContentType; AResponseInfo.ContentLength := AResponseInfo.ContentStream.Size; AResponseInfo.ResponseNo := client.ResponseCode; AResponseInfo.ServerSoftware := client.Response.Server; AResponseInfo.WriteHeader; AResponseInfo.WriteContent; AResponseInfo.ContentStream.Free; client.Free; end; |
Re: TidHTTP.Post() - Parameter werden nicht getrennt
Danke für das Testen, habe mein Programm an Deine Vorlage angepasst. (Letztendlich also die Initialisierung des HTTP-Clients, die direkte Übergabe der Params an Post() und *räusper* die Freigabe am Ende.)
Geholfen hat es leider nichts, stattdessen kommt jetzt überhaupt nichts mehr an, statt wie zuvor alles in einem Parameter. Wir scheinen verschiedene Indy-Versionen zu benutzen, da der Client bei mir die Member "AllowCookies" und " CookieManager" nicht kennt. (Aber ich schleuse die "Cookie:"- und "SetCookie:"-HTTP-Felder sowieso nur durch.) Allerdings halte ich es für unwahrscheinlich, dass die von Borland offiziell mit Delphi 6 ausgelieferte Indy-Version einen so gravierenden Fehler enthält. Zur Sicherheit noch das verwendete PHP-Skript:
Code:
Naja, da dürfte eigentlich nichts schief laufen, insbesondere da beim Aufruf über ein Formular ohne zwischengeschalteten Proxy die korrekten Werte ausgegeben werden.
<?php
echo "id=$_POST["id"] "; echo "nick=$_POST["nick"] "; echo "mail=$_POST["mail"] "; echo "msg=$_POST["msg"] "; ?> |
Re: TidHTTP.Post() - Parameter werden nicht getrennt
ich hab nicht alles gelesen, nur kurz meine erfahrungen zu indy-post;
1. es empfiehlt sich mit nem networksniffer die daten die übetragen werden zu überprüfen einfach um nicht von möglichen fehlern in der serversoftware abhängig zu sein. 2. ich hab es mit indy 9 noch nie geschafft post mit TStringlist erfolgreich abzuschicken, er hat die argumente einfach nicht angehängt, stattdessen habe ich TIdMultiPartFromData verwendet, was bei mir ohne fehler ging. Gruß Thomas |
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:19 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz