TIdHTTP.Post, jak zakodować dane

0

Witam

Potrzebuję użyć metody post żeby przekazać dane do pewnej strony. Jako że nie robiłem tego wcześniej mam wrażenie że trochę błądzę. W zasadzie całość mam już rozpykaną. Pytanie moje dotyczy tego jak trzeba zakodować dane przekazywane do tego post'a.
Mój kod jest taki:


var theIdHTTP : TIdHTTP;
    theData : TStringStream;
    fIdSSLIOHandlerSocketOpenSSL : TIdSSLIOHandlerSocketOpenSSL;
Begin
  Result := '';
  theIdHTTP := TIdHTTP.Create(nil);
  fIdSSLIOHandlerSocketOpenSSL := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
  theData := TStringStream.Create(aData);
  try
    try
      theIdHTTP.IOHandler := fIdSSLIOHandlerSocketOpenSSL;
      theIdHTTP.Request.ContentType := 'application/x-www-form-urlencoded';      
      theIdHTTP.Request.Password := aPass;
      theIdHTTP.Request.Username := aUser;
      theIdHTTP.HTTPOptions := theIdHTTP.HTTPOptions + [hoInProcessAuth];
      Result := theIdHTTP.Post(aURL, theData);
    except
      on E : Exception do
        Begin
          aErrorMsg := E.Message;
        End;
    end;
  finally
    theData.Free;
    fIdSSLIOHandlerSocketOpenSSL.Free;
    theIdHTTP.Free;
  end;

Jako aData przekazuję pewnego strnig'a postaci:

aData := 'zapisz=dodaj&p1=i tutaj tak około 5MB tekstu z różnymi znakami';

Czyli potrzebuję tak naprawdę dwa parametry: zapisz i p1. Nie mogłem zaczaić dlaczego tylko część danych z 5MB się wysyła (wypisywał mi to skrypt PHP). W końcu przenalizowałem te dane i trafiłem że był tam znak '&'. Pogooglowałem trochę, i postanowiłem że zrobię StringReplace('5MB danych', '&', '%26', [rfReplaceAll]) no i zadziałało. Ale coś mi się to nie podoba - pewnie jakieś inne znaki też pasowało by zakodować.

Pytania:

  • jakiej funkcji użyć do zakodowania wartości parametrów
  • a może ContentType mam źle ustawiony
  • a może jest jakaś klasa typu ParamBuilder ?

Z góry dzięki.
b

0

Tak naprawdę nigdy nie szukałem czegoś gotowego do tego ale na swoje potrzeby jakiś czas temu zrobiłem coś takiego:

function SpecialChars(Value: string): string;
begin
  result:= StringReplace(Value, '<', '%3C', [rfReplaceAll]);
  result:= StringReplace(result, '>', '%3E', [rfReplaceAll]);
  result:= StringReplace(result, '"', '%22', [rfReplaceAll]);
  result:= StringReplace(result, '#', '%23', [rfReplaceAll]);
  result:= StringReplace(result, ':', '%3A', [rfReplaceAll]);
  result:= StringReplace(result, '/', '%2F', [rfReplaceAll]);
  result:= StringReplace(result, '?', '%3F', [rfReplaceAll]);
  result:= StringReplace(result, '=', '%3D', [rfReplaceAll]);
  result:= StringReplace(result, '+', '%2B', [rfReplaceAll]);
  result:= StringReplace(result, ' ', '+', [rfReplaceAll]);
  result:= StringReplace(result, #$0A, '%0A', [rfReplaceAll]);
  result:= StringReplace(result, #$0D, '%0D', [rfReplaceAll]);
  result:= StringReplace(result, #$09, '%09', [rfReplaceAll]);
  result:= StringReplace(result, '&', '%26', [rfReplaceAll]);
end;

może nie jest to idealna funkcja ale jak do tej pory użyta w kilku projektach sprawdza się.

0

Nie rozumiem co ty chcesz zrobić bo połączenie masz szyfrowane (SSL), IdHTTP z tego co pamiętam to nie działał przy wysyłaniu metodą post danych,
zapis danych zapisz=dodaj&p1=i tutaj obowiązuje tylko przy metodzie GET (znak &), gdy wysyłasz dane metodą post to dane są zapisywane jako strumień z podanym rozmiarem by server wiedział gdzie zaczyna się dana a gdzie kończy, dla PHP dane które byś przesłał by wyglądały tak, że do zmiennej "zapisz" przypisałeś dane "dodaj&p1=i... " itd. ale mogę się mylić (co do Indy) bo korzystam aktualnie z Synapse.

0

Chodzi o to że normalnie nie da się przesłać metodą post np. takich danych:
wart=1&adres=http://costam/costtam&hash=434555s3== tylko trzeba go zmienić na:
wart=1&adres=http%3A%2F%2Fcostam%2Fcosttam&hash=434555s3%3D%3D
Funkcja którą podałem wcześniej właśnie to robi tylko nie jestem pewien czy zawiera wszystkie znaki które trzeba zmienić.

0

Tak, ale kolega wysyła dane metopą POST a nie GET (POST można używać znaków $<& itd.) tzn dane są zawarte w pamięci a nie przykazywane w adresie i nie ma potrzeby zamiany tych znaków, Chciałbym dodać również że kolega chce wysyłać dane o rozmiarze ok 5MB, na darmowych hostingach php czy apache (nie pamiętam dokładnie) ma ograniczenie do ilu MB można przesłać dane, bo jak jest d 4 to nie wyśle textu/pliku

0
kAzek napisał(a)

Tak naprawdę nigdy nie szukałem czegoś gotowego do tego ale na swoje potrzeby jakiś czas temu zrobiłem coś takiego:

function SpecialChars(Value: string): string;
begin
result:= StringReplace(Value, '<', '%3C', [rfReplaceAll]);
result:= StringReplace(result, '>', '%3E', [rfReplaceAll]);
result:= StringReplace(result, '"', '%22', [rfReplaceAll]);
result:= StringReplace(result, '#', '%23', [rfReplaceAll]);
result:= StringReplace(result, ':', '%3A', [rfReplaceAll]);
result:= StringReplace(result, '/', '%2F', [rfReplaceAll]);
result:= StringReplace(result, '?', '%3F', [rfReplaceAll]);
result:= StringReplace(result, '=', '%3D', [rfReplaceAll]);
result:= StringReplace(result, '+', '%2B', [rfReplaceAll]);
result:= StringReplace(result, ' ', '+', [rfReplaceAll]);
result:= StringReplace(result, #$0A, '%0A', [rfReplaceAll]);
result:= StringReplace(result, #$0D, '%0D', [rfReplaceAll]);
result:= StringReplace(result, #$09, '%09', [rfReplaceAll]);
result:= StringReplace(result, '&', '%26', [rfReplaceAll]);
end;

może nie jest to idealna funkcja ale jak do tej pory użyta w kilku projektach sprawdza się.

No właśnie chciałem coś pewnego : ) Szperałem jeszcze na necie i znalazłem że w IdURI jest funkcja URLEncode. Ale nie wiedzieć czemu lista UnsafeChars = '*<>#%"{}|\^[]`' nie zawiera &.
No nic może nie ma co kombinować tylko skorzystać z Twojego kodu. W sumie trzeba chyba jeszcze przekodowywać znak '%'. I tak dziwnie zrobiłeś z tym '+' - ostatecznie plusy zostaną tam gdzie były spacje - no ale może tak ma być.
Najdziwniejsze jest to że oprócz tego znaku & nie zmieniełem nic innego i poszło, a była cała masa innych znaków - muszę jeszcze sprawdzić czy parser PHP to dobrze przetworzył.

Reasumując dzięki.

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0