Entwickler-Ecke

Internet / Netzwerk - IdHTTP.Post - & in den postdaten


the-kecks - Sa 17.10.09 15:12
Titel: IdHTTP.Post - & in den postdaten
hi,
ich möchte per IdHTTP Daten an einen Server schicken. Wie sicher bekannt ist, werden die Postdaten durch ein & getrennt. Nun habe ich in den postdaten einen Link, in dem & vorkommt und den ich nicht weglassen kann.
Meine Frage: wie bekomme ich es hin, dass der server das & zeichen nicht als trennung der postdaten erkennt, sondern als teil eines der Postdaten?

mfg


Yogu - Sa 17.10.09 16:16

Hallo,

ich denke mal, du kannst alle Zeichen mit einem Prozentzeichen (%) und dem hexadezimalen Wert escapen: %20 wird zum Leerzeichen; %26 wird zum kaufmännischen Und (&). Probier doch das mal aus.

& in der Wikipedia [http://de.wikipedia.org/wiki/%26#Darstellung_in_Computersystemen_und_Ersetzung]

Grüße,
Yogu


the-kecks - Sa 17.10.09 17:08

habs mit %26 probiert, der Link lässt sich nicht öffnen wenn man draufklickt :(
(mit #38 hab ichs auch probiert, aber da werden die postdaten wieder abgeschnitten)

mfg


Yogu - Sa 17.10.09 21:06

user profile iconthe-kecks hat folgendes geschrieben Zum zitierten Posting springen:
habs mit %26 probiert, der Link lässt sich nicht öffnen wenn man draufklickt :(

Links werden aber immer so codiert. Was meinst du damit, wenn du sagst, der Link lasse sich nicht öffnen? Was passiert genau mit den POST-Daten, die an den Server geschickt werden? Wie sieht das Script aus, das sie speichert und an den Browser schickt, der das ganze zu einem Link umwandelt?

user profile iconthe-kecks hat folgendes geschrieben Zum zitierten Posting springen:
(mit #38 hab ichs auch probiert, aber da werden die postdaten wieder abgeschnitten)

Da ist logisch, denn #38 wird bereits von Delphi zu '&' umgewandelt :idea:


the-kecks - Sa 17.10.09 22:03

Zitat:
Da ist logisch, denn #38 wird bereits von Delphi zu '&' umgewandelt :idea:

probieren kann mans ja mal ;)

link im kontext:

Quelltext
1:
url=http://**********/pms.php?action=newpm&userid=**********                    


Moderiert von user profile iconNarses: Code-Tags hinzugefügt


Yogu - Sa 17.10.09 22:06

Ja gut, aber was passiert denn mit diesem Link? In welchem Programm "klickst" du auf ihn? Ist es ein Browser, wird er in HTML-Tags eingeschlossen? Wie sieht dann der HTML-Tag aus?


the-kecks - Sa 17.10.09 22:20

user profile iconYogu hat folgendes geschrieben Zum zitierten Posting springen:

& in der Wikipedia [http://de.wikipedia.org/wiki/%26#Darstellung_in_Computersystemen_und_Ersetzung]

So...halt eine verlinkung im browser.

mfg


Yogu - Sa 17.10.09 22:41

Könntest du mal den HTML-Quelltext rund um den Link posten?


the-kecks - Sa 17.10.09 23:00


Quelltext
1:
<span style="color: blue"> [b] url=http://**********/pms.php?action=newpm&userid=**********]*****[/url][/b]</span>                    


mfg


Yogu - So 18.10.09 12:24

user profile iconthe-kecks hat folgendes geschrieben Zum zitierten Posting springen:

Quelltext
1:
<span style="color: blue"> [b] url=http://**********/pms.php?action=newpm&userid=**********]*****[/url][/b]</span>                    

Sowas kann man doch gar nicht anklicken, das ist ja das reinste Chaos. Sind die ganzen kaputten BB-Codes etwa Absicht? Und das &-Zeichen ist doch richtig dargestellt, damit gibt's doch offensichtlich keine Probleme...


the-kecks - So 18.10.09 16:57

ja die sind absicht, da ich den quelltext des BBCodes zeigen wollte...
also:
Normal gepostet:
[url=http://**********/pms.php?action=newpm&userid=**********]hallo[/url]

Mit IdHTTP:
[color=blue][b][url=http://**********/pms.php?action=newpm <-- wird ab dem & abgeschnitten

mfg


Andreas L. - So 18.10.09 17:35

user profile iconthe-kecks hat folgendes geschrieben Zum zitierten Posting springen:
ja die sind absicht, da ich den quelltext des BBCodes zeigen wollte...
also:
Normal gepostet:
[url=http://**********/pms.php?action=newpm&userid=**********]hallo[/url]

Mit IdHTTP:
[color=blue][b][url=http://**********/pms.php?action=newpm <-- wird ab dem & abgeschnitten

mfg


Sehe ich das richtig, du schickst die URL mit TIdHTTP.Post?
Dann musst du anstatt Post die Methode Get verwenden:

Delphi-Quelltext
1:
2:
3:
4:
5:
var
  s: String;
begin
  S := IdHTTP1.Get('http://**********/pms.php?action=newpm&userid=**********');
end;


LexXis - So 18.10.09 18:46

Wandle alle Sonderzeichen in %[Hex] um und setzte vor dem Absenden IdHTTP1.Request.ContentType := 'application/x-www-form-urlencoded';

//EDIT: Zum besseren Verständnis: Ich meine die Sonderzeichen in deinen POST-Daten. Mitunter das '&'..

Hab das gerade mal lokal mit Firefox, xamplite und NetCat ausprobiert, funktioniert einwandfrei :)


the-kecks - So 18.10.09 21:28

ich möchte daten an einen server schicken nicht holen...
D.h. ich mache einen post wie hier im forum. Dabei muss unter jedem post dieser bbCode stehen:

Delphi-Quelltext
1:
2:
3:
4:
5:
var Params : TStringlist;
...
Params.Add('blabla');
Params.Add(Nachricht + bbCode);  //post + dieser bbCode mit der URL
IdHTTP1.Post(URL, Params);

hoffe jetzt ist es verständlicher ;)

mfg


Yogu - So 18.10.09 22:01

Zeig doch mal, was am Ende Params.Text steht.

Du könntest die Daten auch mal an http://yogu.bplaced.net/post.php schicken und schauen, was dort angezeigt wird. Wenn Das & im Browser als normales & angezeigt wird, stimmt die Übertragung und es hakt am Forum. Dann könnte man manche Fehlerquellen schon mal ausschließen.


the-kecks - So 18.10.09 22:05

die Fehlerquelle ist doch ganz klar. Dieser tag wird abgeschnitten, weil indy denkt das & wäre die trennung zwischen 2
Datensätzen.

mfg


LexXis - So 18.10.09 22:10

Darf ich nochmal auf meinen letzten Post hinweisen? Der beschreibt ziemlich genau die Lösung für dein Problem mit der Trennung der Parameter.. ;)


the-kecks - So 18.10.09 23:05

funzt leider nicht

mfg


LexXis - So 18.10.09 23:23

Dann lass doch mal ein wenig Quelltext sehen, vielleicht finden wir den Fehler ja noch :)
Besonders interessieren würde mich der Teil in dem du die Sonderzeichen umwandelst und der in dem du deine Anfrage abschickst.


the-kecks - Mo 19.10.09 00:00

hab deine methode nur mal provesorisch getestet...hab IdHTTP Contenttype umgestellt dann mich mit IdHTTP hier eingeloggt und meinen post (der 7 mal editiert wurde deswegen^^) editiert.

mfg


Yogu - Mo 19.10.09 17:50

user profile iconLexXis hat folgendes geschrieben Zum zitierten Posting springen:
Wandle alle Sonderzeichen in %[Hex] um und setzte vor dem Absenden IdHTTP1.Request.ContentType := 'application/x-www-form-urlencoded';


user profile iconthe-kecks hat folgendes geschrieben Zum zitierten Posting springen:
hab deine methode nur mal provesorisch getestet...hab IdHTTP Contenttype umgestellt dann mich mit IdHTTP hier eingeloggt und meinen post (der 7 mal editiert wurde deswegen^^) editiert.

Das war aber sehr provisorisch - da fehlt sogar die Hälfte :!: Zeigt doch mal die Methode, mit der du
user profile iconLexXis hat folgendes geschrieben Zum zitierten Posting springen:
alle Sonderzeichen in %[Hex] um[wandelst]


the-kecks - Mo 19.10.09 19:17

ich hatte gar keine methode...ich hab die einfach von hand eingebaut.

mfg


Yogu - Mo 19.10.09 19:24

user profile iconthe-kecks hat folgendes geschrieben Zum zitierten Posting springen:
ich hatte gar keine methode...ich hab die einfach von hand eingebaut.

Dann zeig doch bitte schön den Quelltext, den du so schön von Hand geschrieben hast... so kommen wir doch nicht weiter! :roll:

Edit: Oh, sorry - ich dachte, du hättest die Methode von Hand eingebaut, dabei waren es wahrscheinlich die Zeichen, oder? :oops:

Hm, das hieße dann ja, dass das IdHTTP die encodierten Zeichen umwandelt. Wäre aber sehr seltsam. Hast du jetzt mal die von mir oben verlinkte [http://www.delphi-forum.de/viewtopic.php?p=581730#581730[/url] Seite als Ziel ausprobiert? Wenn ja, was zeigt die für POST-Daten an?


the-kecks - Mo 19.10.09 19:33

ja, hab die zeichen von hand eingebaut.
deine seite hab ich probiert, hab daten an server geschickt (HTMLCOde:=IdHTTP1.Post(Link, '%20%26%20');)
HTMLCode zeigte aber nur den normalen quelltext an (hab ich was falsch gemacht?). Daraufhin habe ich es dann hier im forum versucht

mfg


Yogu - Mo 19.10.09 20:24

user profile iconthe-kecks hat folgendes geschrieben Zum zitierten Posting springen:

Delphi-Quelltext
1:
HTMLCOde:=IdHTTP1.Post(Link, '%20%26%20');                    

Das läuft doch nichtmal durch den Compiler durch, wieso postest es dann hier? (Oder ist bei dir als zweiter Parameter ein String möglich?)

Ich hab das ganze jetzt mal nachgestellt:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
function HTTPEncode(const AStr: string): string;
const
  NoConversion = ['A'..'Z''a'..'z''*''@''.''_''-'];
var
  Sp, Rp: PChar;
begin
  SetLength(Result, Length(AStr) * 3);
  Sp := PChar(AStr);
  Rp := PChar(Result);
  while Sp^ <> #0 do
  begin
    if Sp^ in NoConversion then
      Rp^ := Sp^
    else if Sp^ = ' ' then
      Rp^ := '+'
    else
    begin
      FormatBuf(Rp^, 3'%%%.2x'6, [Ord(Sp^)]);
      Inc(Rp, 2);
    end;
    Inc(Rp);
    Inc(Sp);
  end;
  SetLength(Result, Rp - PChar(Result));
end;

procedure TForm1.FormCreate(Sender: TObject);
var HTTP: TIdHTTP; Response: String; Data: TStringList;

  procedure AddData(Name, Value: String);
  begin
    Data.Values[HTTPEncode(Name)] := HTTPEncode(Value);
  end;

begin
  Data := TStringList.Create;
  HTTP := TIdHTTP.Create;
  try
    AddData('url''http://example.com/test?blah=blubb&foo=bar');
    AddData('color''red');

    HTTP.Request.ContentType := 'application/x-www-form-urlencoded';
    Response := HTTP.Post('http://yogu.bplaced.net/post.php', Data);

    inpOutput.Lines.Text := Response;
  finally            
    FreeAndNil(HTTP);
    FreeAndNil(Data);
  end;
end;

Die Funktion HTTPEncode habe ich von tutorials.de [http://www.tutorials.de/forum/delphi-kylix-pascal/141381-daten-per-post-mittels-indy-verschicken.html#post729586].

Dieses Programm macht folgende Ausgabe:


Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
<?xml version="1.0" encoding="iso-8859-1" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>POST</title>
  </head>
  <body>
    <h1>POST Data</h1>
    <ul>
      <li><b>url:</b> http%3A%2F%2Fexample.com%2Ftest%3Fblah%3Dblubb%26foo%3Dbar</li>
      <li><b>color:</b> red</li>
    </ul>
  </body>
</html>

Seltsam ist, dass die encodierten Zeichen nicht vom Server in Sonderzeichen umgewandelt werden. Mein Script würde HTML-eigene Zeichen, also auch das kaufmännische Und (&), in z.B. &: umwandeln. Hier ist aber die %-Codierung noch vorhanden, was mich ziemlich verwirrt. Aber auf jeden Fall werden beide Parameter mit übergeben, und das ist ja dein Hauptanliegen.

URLS sollten übrigens sowieso in dieser %-Schreibweise bleiben, aber darum sollte sich das Forum kümmern.

Grüße,
Yogu


the-kecks - Mo 19.10.09 21:03

erstmal danke für deine mühe mit diesem post :)

ich hatte den orignal code nicht mehr mit dem ich es ausprobiert hatte, daher hab ich schnell was hingeschrieben^^
mein hauptanliegen ist eigentlich, dass die postdaten nicht abgeschnitten werden und dass das & korrekt dargestellt wird.

mfg


Yogu - Mo 19.10.09 21:45

user profile iconthe-kecks hat folgendes geschrieben Zum zitierten Posting springen:
mein hauptanliegen ist eigentlich, dass die postdaten nicht abgeschnitten werden

Soweit klappt's mit meinem Beispiel, könntest du das mal bei dir ausprobieren?

user profile iconthe-kecks hat folgendes geschrieben Zum zitierten Posting springen:
und dass das & korrekt dargestellt wird.

Das ist eben das Problem. Aber vielleicht klappt es bei deinem Forum trotzdem.


the-kecks - Mo 19.10.09 22:35

ich hab es ja ausprobiert und es klappt auch, aber der link ist dann http://....%26.../ und den öffnet der browser nicht ;)

mfg


LexXis - Di 20.10.09 00:55

user profile iconthe-kecks hat folgendes geschrieben Zum zitierten Posting springen:
[...] http://....%26.../ [...]

Welchen Browser verwendest du denn? Firefox 3.5.3 macht da in meinem Fall brav ein '&' in der URL draus :shock:
Kurz zu meinem Lösungsansatz (sollte selbsterklärend sein)

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
function TForm1.EncodeURL(F: String): String;
var
  i: Integer;
begin
  Result := '';

  for i := 1 to Length(F) do
    if not (F[i] in ['a'..'z''A'..'Z''0'..'9''.']) then
      Result := Result + '%' + IntToHex(Ord(F[i]), 2)
    else
      Result := Result + F[i];
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  Post: TStringStream;
  PostStr: String;
begin
  PostStr := 'url='+EncodeURL('http://www.delphi-forum.de/viewtopic.php?'+
    't=95398&start=0&postorder=asc');
  Post := TStringStream.Create(PostStr);
  IdHTTP1.Request.ContentType := 'application/x-www-form-urlencoded';
  ShowMessage(IdHTTP1.Post('http://127.0.0.1/', Post));
  Post.Free;
end;


Hab das ganze wie gesagt nur lokal mit xamplite getestet. In meiner Index.php steht daher auch ganz banal nur

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
<?PHP
  if( isset($_POST['url']) ) {
    echo '<a href="' . $_POST['url'] . '">' . $_POST['url'] . '</a>';
  }
?>


<form action="http://127.0.0.1/" method="post">
  <input type="text" name="url" /><input type="submit" />
</form>


Apache serviert mir daraufhin wie gewünscht einen Link mit dem gewünschten Ziel.


the-kecks - Di 20.10.09 21:45

ich benutze firefox 3.5.3 und es geht trotzdem nicht...
code:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
function EncodeURL(F: String): String;
var
  i: Integer;
begin
  Result := '';

  for i := 1 to Length(F) do
    if not (F[i] in ['a'..'z''A'..'Z''0'..'9''.']) then
      Result := Result + '%' + IntToHex(Ord(F[i]), 2)
    else
      Result := Result + F[i];
end;

procedure TForm1.Button1Click(Sender: TObject);
var Params : TStringlist;
begin
  Params := TStringlist.Create;
  Params.Add('url=' + EncodeURL('hallo&hallo'));
  Params.Add('url2=hallo');
  Memo1.Text:=IdHTTP1.Post('http://yogu.bplaced.net/post.php', Params);


yogu.bplaced.net quelltext:

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
<?xml version="1.0" encoding="iso-8859-1" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>POST</title>
  </head>
  <body>
    <h1>POST Data</h1>
    <ul>
      <li><b>url:</b> hallo%26hallo</li>
      <li><b>url2:</b> hallo</li>
    </ul>
  </body>
</html>


mfg


Yogu - Di 20.10.09 22:31

Hm, ok, so sah es bei mir auch aus. Wenn du die URL jetzt aber noch in <a></a>-Tags (bzw. in entsprechende BB-Codes) packst, sollte der Browser den Link richtig darstellen und aufrufen.

Bei URLS sind solche %er-Escapes gültig, in HTML nicht. Irgendwie müsste man es hinbekommen, dass der Server die POST-Daten direkt umsetzt. Dafür ist eigentlich folgende Zeile zuständig:

user profile iconYogu hat folgendes geschrieben Zum zitierten Posting springen:

Delphi-Quelltext
 
42:
{ ... }
    HTTP.Request.ContentType := 'application/x-www-form-urlencoded';

Vielleicht weiß jemand anderes, was hier schief läuft. Ich jedenfalls nicht.