我想在应用程序中调用一个Web服务,可以通过导入WSDL或者使用URL和参数的"HTTP GET"来使用它。因此,我更喜欢后者,因为它比较简单。
我知道我可以使用Indy IdHTTP.get完成这项工作,但这很简单,我不想在我的应用程序中添加复杂的Indy代码。
更新: 抱歉如果我表达不清楚,我所说的"不想添加复杂的Indy代码"是指我不想为了这个简单的任务而添加Indy组件,并希望有更轻量级的方法。
我想在应用程序中调用一个Web服务,可以通过导入WSDL或者使用URL和参数的"HTTP GET"来使用它。因此,我更喜欢后者,因为它比较简单。
我知道我可以使用Indy IdHTTP.get完成这项工作,但这很简单,我不想在我的应用程序中添加复杂的Indy代码。
更新: 抱歉如果我表达不清楚,我所说的"不想添加复杂的Indy代码"是指我不想为了这个简单的任务而添加Indy组件,并希望有更轻量级的方法。
使用Indy调用RESTful Web服务非常简单。
在您的uses子句中添加IdHTTP。请记住,IdHTTP需要在您的URL上添加“HTTP://”前缀。
function GetURLAsString(const aURL: string): string;
var
lHTTP: TIdHTTP;
begin
lHTTP := TIdHTTP.Create;
try
Result := lHTTP.Get(aURL);
finally
lHTTP.Free;
end;
end;
TIdHTTP.Create(nil);
可以简写为 TIdHTTP.Create;
。 - mjn您可以像这样使用WinINet API:
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;
源代码:http://www.scalabium.com/faq/dct0080.htm
WinINet API使用与InternetExplorer相同的工具,因此您也可以免费获取由InternetExplorer设置的任何连接和代理设置。
TIdHTTP
组件在返回响应体作为string
时会自动处理这些转换。 - Remy Lebeau实际上,被接受的答案中的代码对我没有起作用。所以我稍微修改了一下,使它能够返回字符串并在执行后优雅地关闭所有内容。示例将检索到的数据作为UTF8String返回,因此对于ASCII和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;
希望这对像我一样在寻找如何在Delphi中检索页面内容的简单代码的人有所帮助。 祝愿, Aldis :)
System.Net.HttpClient
单元中的THTTPClient
,因为它是标准并且跨平台的。简单示例如下: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;
except
来处理HTTP错误吗? - undefinedprocedure 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;
使用此功能时,还可以获取进度通知。只需将事件处理程序分配给TDownloadURL的OnDownloadProgress事件即可。
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;
在上述代码中,我假设COM已经为主VCL线程初始化。据报道,这可能不是简单应用程序或LCL应用程序的情况。同时,它肯定不适用于异步(多线程)工作。
以下是正在运行的真实代码片段。请注意-这只是额外的功能。不需要工作。所以虽然我会发出请求,但我不关心它们的结果,结果被忽略并转储。
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;
CoInitialize(nil);
和 CoUninitialize
。 - supersanCoInitialize
和CoUninitialize
方法后,关闭应用程序时出现了崩溃的情况。仅供参考。 - supersanPromptForFileName
函数,但实际上整个子系统都不行。原来,在 XE2 中,保存/打开功能是通过 COM 实现的,并且该函数在线程中被调用,因此 Windows 发出了 COM 未初始化错误信号,并被 VCL 吞噬。然而,由于 TOpenFileDialog
是标准的 Delphi 组件,并且在主 VCL 线程中简单可靠地工作,这意味着 COM 在主线程中的某个地方被自动初始化了。 - Arioch 'The