Es gibt einen Webdienst, den ich in meiner Anwendung aufrufen möchte. Ich kann ihn beim Importieren der WSDL verwenden oder einfach "HTTP GET" mit der URL und den Parametern verwenden, daher ziehe ich den späteren vor, weil es einfach ist.
Ich weiß, dass ich indy idhttp.get verwenden kann, um den Job zu erledigen, aber dies ist sehr einfach und ich möchte meiner Anwendung keinen komplexen indy-Code hinzufügen.
UPDATE: Entschuldigung, wenn ich nicht klar war, meinte ich mit "keinen komplexen Indy-Code hinzufügen". Ich möchte nicht, dass Indy-Komponenten nur für diese einfache Aufgabe hinzugefügt werden.
Sie können die WinINet-API wie folgt verwenden:
uses WinInet;
function GetUrlContent(const Url: string): string;
var
NetHandle: HINTERNET;
UrlHandle: HINTERNET;
Buffer: array[0..1024] of Char;
BytesRead: dWord;
begin
Result := '';
NetHandle := InternetOpen('Delphi 5.x', INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
if Assigned(NetHandle) then
begin
UrlHandle := InternetOpenUrl(NetHandle, PChar(Url), nil, 0, INTERNET_FLAG_RELOAD, 0);
if Assigned(UrlHandle) then
{ UrlHandle valid? Proceed with download }
begin
FillChar(Buffer, SizeOf(Buffer), 0);
repeat
Result := Result + Buffer;
FillChar(Buffer, SizeOf(Buffer), 0);
InternetReadFile(UrlHandle, @Buffer, SizeOf(Buffer), BytesRead);
until BytesRead = 0;
InternetCloseHandle(UrlHandle);
end
else
{ UrlHandle is not valid. Raise an exception. }
raise Exception.CreateFmt('Cannot open URL %s', [Url]);
InternetCloseHandle(NetHandle);
end
else
{ NetHandle is not valid. Raise an exception }
raise Exception.Create('Unable to initialize Wininet');
end;
quelle: http://www.scalabium.com/faq/dct0080.htm
Die WinINet-API verwendet die gleichen Funktionen, die auch InternetExplorer verwendet, sodass Sie auch alle Verbindungs- und Proxy-Einstellungen erhalten, die von InternetExplorer kostenlos festgelegt wurden.
Ein RESTful-Webdienst mit Indy aufzurufen, ist ziemlich einfach.
Fügen Sie Ihrer Anwendungsklausel IdHTTP hinzu. Denken Sie daran, dass IdHTTP das Präfix "HTTP: //" für Ihre URLs benötigt.
function GetURLAsString(const aURL: string): string;
var
lHTTP: TIdHTTP;
begin
lHTTP := TIdHTTP.Create;
try
Result := lHTTP.Get(aURL);
finally
lHTTP.Free;
end;
end;
Eigentlich hat der Code in der akzeptierten Antwort für mich nicht funktioniert. Also habe ich es ein wenig geändert, so dass es tatsächlich String zurückgibt und alles nach der Ausführung ordnungsgemäß schließt. Beispiel gibt die abgerufenen Daten als UTF8String zurück, sodass sie sowohl für ASCII als auch für UTF8-Seiten geeignet sind.
uses WinInet;
function GetUrlContent(const Url: string): UTF8String;
var
NetHandle: HINTERNET;
UrlHandle: HINTERNET;
Buffer: array[0..1023] of byte;
BytesRead: dWord;
StrBuffer: UTF8String;
begin
Result := '';
NetHandle := InternetOpen('Delphi 2009', INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
if Assigned(NetHandle) then
try
UrlHandle := InternetOpenUrl(NetHandle, PChar(Url), nil, 0, INTERNET_FLAG_RELOAD, 0);
if Assigned(UrlHandle) then
try
repeat
InternetReadFile(UrlHandle, @Buffer, SizeOf(Buffer), BytesRead);
SetString(StrBuffer, PAnsiChar(@Buffer[0]), BytesRead);
Result := Result + StrBuffer;
until BytesRead = 0;
finally
InternetCloseHandle(UrlHandle);
end
else
raise Exception.CreateFmt('Cannot open URL %s', [Url]);
finally
InternetCloseHandle(NetHandle);
end
else
raise Exception.Create('Unable to initialize Wininet');
end;
Ich hoffe, es hilft jemandem wie mir, der einen einfachen Code zum Abrufen von Seiteninhalten in Delphi gesucht hat .. _. Prost, Aldis :)
Wenn Sie eine Datei herunterladen möchten, können Sie TDownloadURL aus der ExtActns-Einheit verwenden. Viel einfacher als die direkte Verwendung von WinInet.
procedure TMainForm.DownloadFile(URL: string; Dest: string);
var
dl: TDownloadURL;
begin
dl := TDownloadURL.Create(self);
try
dl.URL := URL;
dl.FileName := Dest;
dl.ExecuteTarget(nil); //this downloads the file
finally
dl.Free;
end;
end;
Es ist auch möglich, Fortschrittsbenachrichtigungen zu erhalten, wenn Sie dies verwenden. Weisen Sie dem Ereignis OnDownloadProgress von TDownloadURL einfach einen Ereignishandler zu.
In neueren Delphi-Versionen ist es besser, THTTPClient
von System.Net.HttpClient
unit zu verwenden, da es Standard und plattformübergreifend ist. Ein einfaches Beispiel ist
function GetURL(const AURL: string): string;
var
HttpClient: THttpClient;
HttpResponse: IHttpResponse;
begin
HttpClient := THTTPClient.Create;
try
HttpResponse := HttpClient.Get(AURL);
Result := HttpResponse.ContentAsString();
finally
HttpClient.Free;
end;
end;
Die Verwendung der Windows-HTTP-API ist möglicherweise auch einfach.
procedure TForm1.Button1Click(Sender: TObject);
var http: variant;
begin
http:=createoleobject('WinHttp.WinHttpRequest.5.1');
http.open('GET', 'http://lazarus.freepascal.org', false);
http.send;
showmessage(http.responsetext);
end;
Im obigen Code impliziere ich, dass COM bereits für den Haupt-VCL-Thread initialisiert wurde. Angeblich ist dies bei simplen Apps oder bei LCL-Apps nicht immer der Fall. Bei einer asynchronen (Multithread-) Arbeit wäre dies definitiv nicht der Fall.
Unten sehen Sie den Ausschnitt aus dem echten Code. Hinweis - die Funktionalität ist Bonus. Es ist nicht erforderlich zu arbeiten. Während ich Anfragen ausstelle, kümmere ich mich nicht um ihre Ergebnisse, dieses Ergebnis wird ignoriert und ausgegeben.
procedure TfmHaspList.YieldBlinkHTTP(const LED: boolean; const Key_Hardware_ID: cardinal);
var URL: WideString;
begin
URL := 'http://127.0.0.1:1947/action.html?blink' +
IfThen( LED, 'on', 'off') + '=' + IntToStr(Key_Hardware_ID);
TThread.CreateAnonymousThread(
procedure
var Request: OleVariant;
begin
// COM library initialization for the current thread
CoInitialize(nil);
try
// create the WinHttpRequest object instance
Request := CreateOleObject('WinHttp.WinHttpRequest.5.1');
// open HTTP connection with GET method in synchronous mode
Request.Open('GET', URL, False);
// set the User-Agent header value
// Request.SetRequestHeader('User-Agent', 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0');
// sends the HTTP request to the server, the Send method does not return
// until WinHTTP completely receives the response (synchronous mode)
Request.Send;
// // store the response into the field for synchronization
// FResponseText := Request.ResponseText;
// // execute the SynchronizeResult method within the main thread context
// Synchronize(SynchronizeResult);
finally
// release the WinHttpRequest object instance
Request := Unassigned;
// uninitialize COM library with all resources
CoUninitialize;
end;
end
).Start;
end;
Verwenden Sie die Funktion Synapse TCP/IP in der HTTPSEND-Einheit ( HTTPGetText, HTTPGetBinary ). Es wird den HTTP-Pull für Sie ausführen und erfordert keine externen DLLs außer Winsock. Die neueste SVN-Version funktioniert in Delphi 2009 einwandfrei. Dabei werden Funktionsaufrufe blockiert, sodass keine Ereignisse programmiert werden müssen.
Update: Die Einheiten sind sehr leicht und basieren nicht auf Komponenten. Die neueste Version von SVN läuft auch in Delphi XE4 einwandfrei.
Wenn Ihre Anwendung nur Windows ist, würde ich empfehlen, WinSock zu verwenden. Es ist einfach genug, erlaubt die Ausführung jeder HTTP-Anfrage, kann sowohl synchron als auch asynchron arbeiten (mit nicht blockierenden WSASend/WSARecv-Rückrufen oder guten alten send/recv in einem dedizierten Thread).