Der Code in #24 funktioniert.
Ich nutze
Indy sonst nicht - nur weil du gefragt hast, habe ich das Ding wieder einmal angeschaut - und es reicht wieder für ein paar Wochen. Ich nutze ICS. Fürs Posten setze ich wohl häufiger TNetHTTPClient, weil diese Komponente direkt mit den Sicherheitsfunktionen (https Unterstützung ohne "Basteln") von Windows interagiert.
Herzlichen Dank für deinen Supertipp "libretranslate" - kannte ich nicht, ist grossartig und es fallen mir viele Dinge ein, welche ich tun würde, wenn ich mehr Zeit hätte...
Dein Tipp "hoForceEncodeParams entfernen" gilt fürs Post mit zweitem Parameter TStringList, da sonst die Daten nur im HTTP Header landen und von libretranslate nicht "gesehen" werden (Bad request). Für post via Stream spielt die Option keine Rolle. Stream wird (wie von libretranslate gewünscht) im Body übertragen.
Wenn ich den
Indy Code anschaue, glaube ich, dass das Posten in diesem Fall mit TStrings nicht klappen kann. Wünsche wie Request.CharSet := 'utf-8'; Request.ContentEncoding := 'utf-8' oder utf8 beim Post als dritten Parameter setzen werden von
Indy nicht berücksichtigt.
Indy behandelt die von dir beim Post als zweiten Parameter übergebene TStringList als Parameter vom Typ par1=val1&par2=val2.... und codiert diese entsprechend via URLEncode. Die ?, welche du gesehen hast waren "nicht druckbare" Zeichen; HEX Monitor nutzen wäre hier u.U. aufschlussreicher. Fiddler ist übrigens grossartig, wenn du http Traffic untersuchen willst.
Kurz: Beim Posten der json Daten statt TStrings einen Stream verwenden löst das Problem.
Ich habe in #24 TMemorystream verwendet. Viel schöner ist es mit einem TStringStream (Copilot hat dies übrigens vorgeschlagen, als ich fragte, ob man den Code vereinfachen oder schöner schreiben könne.) Ich habe nun auch eine Fehlerbehandlung (ich habe Copilot nicht gefragt was KI davon hält
) eingebaut:
Delphi-Quellcode:
function fehler :
string;
var fehlermeldung : PCHar;
begin
getmem( fehlermeldung , 600 );
ExceptionErrorMessage( ExceptObject, ExceptAddr, fehlermeldung, 599 );
Result := fehlermeldung;
end;
function libretranslate_Indy(uebersetze :
string;
var uebersetzung :
string ) : boolean;
// RESULT=false, wenn eine Exception aufgetreten ist
// Bei RESULT=false wird in uebersetzung die Fehlermeldung übergeben
// Bei RESULT=true wird in übersetzung die Serverantwort von libretranslate zurückgeben.
var
JsonToSend : TStringStream;
idhttp : TIdHTTP;
begin
Result := false;
try
JsonToSend := TStringStream.Create(uebersetze, TEncoding.UTF8);
idhttp := TIdHTTP.Create(
nil);
try
idhttp.Request.ContentType := '
application/json';
uebersetzung := UTF8Decode(idhttp.post('
http://127.0.0.1:5000/translate',jsontosend));
Result := true;
finally
jsontosend.free;
idhttp.Free;
end;
except
uebersetzung := fehler;
Result := false;
end;
end;
oder via TNetHTTPClient (SSL Unterstützung)
Delphi-Quellcode:
procedure WriteStringToStream(Stream: TStream; const Str: String);
var
Data: TBytes;
begin
Data := TEncoding.UTF8.GetBytes(Str);
Stream.WriteBuffer(Data[0], Length(Data));
end;
function CreateHTTPClient: TNetHTTPClient;
begin
Result := TNetHTTPClient.Create(nil);
end;
function CreateHTTPRequest(Client: TNetHTTPClient): TNetHTTPRequest;
begin
Result := TNetHTTPRequest.Create(nil);
Result.Client := Client;
Result.CustomHeaders['Content-Type'] := 'application/json';
end;
function CreateParamsStream(const Str: String): TStream;
begin
Result := TMemoryStream.Create;
WriteStringToStream(Result, Str);
Result.Position := 0;
end;
(* SSL/TLS-Details abstrahiert; interagiert direkt mit den Windows-Sicherheitsfunktionen *)
procedure Uebersetze;
var
HTTPClient: TNetHTTPClient;
HTTPRequest: TNetHTTPRequest;
Params: TStream;
Response: IHTTPResponse;
begin
HTTPClient := CreateHTTPClient;
HTTPRequest := CreateHTTPRequest(HTTPClient);
Params := CreateParamsStream(atest);
try
Response := HTTPRequest.Post('http://127.0.0.1:5000/translate', Params);
ShowMessage(Response.ContentAsString(TEncoding.UTF8));
finally
HTTPRequest.Free;
HTTPClient.Free;
Params.free;
end;
end;