web-dev-qa-db-fra.com

Quel est le moyen le plus simple d'appeler l'URL Http GET en utilisant Delphi?

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.

40
Mohammed Nasman

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.

26
Lars Truijens

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;
33
Bruce McGee

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.

14
Aldis

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.

7
Michael Madsen

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;
6
EugeneK

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;
4
Arioch 'The

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.

2
skamradt

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é).

0
user2024154