it-swarm.com.de

Was ist der einfachste Weg, HTTP-GET-URL mit Delphi aufzurufen?

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.

40
Mohammed Nasman

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.

26
Lars Truijens

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

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 :)

14
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.

7
Michael Madsen

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

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

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.

2
skamradt

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

0
user2024154