TIdHTTP.Post, jak zakodować dane

Odpowiedz Nowy wątek
2011-09-20 08:26
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

edytowany 1x, ostatnio: b0bik, 2011-09-20 08:27

Pozostało 580 znaków

2011-09-20 09:40
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ę.


Nie odpowiadam na PW w sprawie pomocy programistycznej.
Pytania zadawaj na forum, bo:
od tego ono jest ;) | celowo nie zawracasz gitary | przeczyta to więcej osób a więc większe szanse że ktoś pomoże.
edytowany 1x, ostatnio: kAzek, 2011-09-20 09:41

Pozostało 580 znaków

2011-09-20 11:03
ProQix Polaczeq
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.

Mam szyfrowane - bo taką mam potrzebę - i IdHTTP działa. Dane w POST są faktycznie zapisywane jako strumień - ale ten strumień też ma swój format. Przecież w tych danym może być więcej niż jedna wartość - dlatego musi mieć ten strumień swoją strukturę. - b0bik 2011-09-20 14:04

Pozostało 580 znaków

2011-09-20 12:42
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ć.


Nie odpowiadam na PW w sprawie pomocy programistycznej.
Pytania zadawaj na forum, bo:
od tego ono jest ;) | celowo nie zawracasz gitary | przeczyta to więcej osób a więc większe szanse że ktoś pomoże.

Pozostało 580 znaków

2011-09-20 13:54
ProQix Polaczeq
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

Mylisz pojęcia. Dane (np formularzy) w metodzie post wysyła się właśnie tak: klucz=wartosc&klucz2=wartosc2&klucz3=wartosc3 http://pl.wikipedia.org/wiki/POST_(metoda) - b0bik 2011-09-20 14:02

Pozostało 580 znaków

2011-09-20 14:09
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.

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

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