Il y a un service Web que je veux appeler dans mon application, je peux l'utiliser pour importer le WSDL ou simplement utiliser "HTTP GET" avec l'URL et les paramètres, je préfère donc le dernier parce que c'est simple.
Je sais que je peux utiliser indy idhttp.get pour faire le travail, mais c’est très simple et je ne veux pas ajouter de code indy complexe à mon application.
UPDATE: désolé si je n'étais pas clair, je voulais dire par "ne pas ajouter de code indy complexe", je ne veux pas ajouter de composants indy pour cette tâche simple, et je préfère un moyen plus léger pour cela.
Vous pouvez utiliser l’API WinINet comme ceci:
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;
source: http://www.scalabium.com/faq/dct0080.htm
L'API WinINet utilise le même contenu qu'InternetExplorer utilise pour que vous obteniez gratuitement tous les paramètres de connexion et de proxy définis par InternetExplorer.
Appeler un service Web RESTful en utilisant Indy est assez simple.
Ajoutez IdHTTP à votre clause uses. N'oubliez pas que IdHTTP a besoin du préfixe "HTTP: //" sur vos URL.
function GetURLAsString(const aURL: string): string;
var
lHTTP: TIdHTTP;
begin
lHTTP := TIdHTTP.Create;
try
Result := lHTTP.Get(aURL);
finally
lHTTP.Free;
end;
end;
En fait, le code dans la réponse acceptée n'a pas fonctionné pour moi. Je l’ai donc modifié un peu pour qu’il retourne String et ferme le tout après exécution. L'exemple retourne les données récupérées sous la forme UTF8String afin que cela fonctionne correctement pour ASCII ainsi que pour les pages UTF8.
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;
J'espère que cela aidera pour quelqu'un comme moi, qui recherchait du code simple, comment récupérer le contenu d'une page dans Delphi.
Si le téléchargement dans un fichier est correct, vous pouvez utiliser TDownloadURL à partir de l'unité ExtActns. Beaucoup plus simple que d'utiliser WinInet directement.
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;
Il est également possible d’obtenir des notifications de progrès lorsque vous utilisez ceci. Attribuez simplement un gestionnaire d'événements à l'événement OnDownloadProgress de TDownloadURL.
Dans les nouvelles versions de Delphi, il est préférable d'utiliser THTTPClient
à partir de System.Net.HttpClient
, car il s'agit d'une solution standard et multiplate-forme. Exemple simple est
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;
L'utilisation de l'API HTTP Windows peut également être facile.
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;
Dans le code ci-dessus, j'implique que COM était déjà initialisé pour le thread principal de la VCL. Il semblerait que cela ne soit pas toujours le cas pour les applications simplistes ou pour les applications LCL. En outre, cela ne serait certainement pas le cas pour le travail asynchrone (multithread).
Vous trouverez ci-dessous le extrait du code réel en cours d'exécution. Remarque - la fonctionnalité est un bonus. Il n'est pas nécessaire de travailler. Ainsi, même si je fais des demandes, je me fiche de leurs résultats, ils sont ignorés et ignorés.
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;
Utilisez la fonction Synapse TCP/IP dans l'unité HTTPSEND ( HTTPGetText, HTTPGetBinary ). Il fera le pull HTTP pour vous et ne nécessite aucune DLL externe autre que Winsock. La dernière version de SVN fonctionne parfaitement avec Delphi 2009. Ceci utilise des appels de fonction bloquants, ainsi aucun événement à programmer.
Mise à jour: Les unités sont très légères et ne sont pas basées sur des composants. La dernière version de SVN fonctionne également parfaitement avec Delphi XE4.
Si votre application ne concerne que Windows, je vous conseillerais d'utiliser WinSock. C'est assez simple, permet d'exécuter n'importe quelle requête HTTP, peut fonctionner de manière synchrone et asynchrone (en utilisant WSASend/WSARecv non bloquant avec des rappels ou un bon vieil envoi/récupération dans un thread dédié).