如何使用 WinInet api 在 Delphi 中发送 HTTP POST 请求 [英] How to send a HTTP POST Request in Delphi using WinInet api
问题描述
我正在尝试使用 WinInet 函数从 Delphi 发出 HTTP 请求.
I am trying to make HTTP Requests from Delphi using the WinInet functions.
到目前为止我有:
function request:string;
var
hNet,hURL,hRequest: HINTERNET;
begin
hNet := InternetOpen(PChar('User Agent'),INTERNET_OPEN_TYPE_PRECONFIG or INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
if Assigned(hNet) then
begin
try
hURL := InternetConnect(hNet,PChar('http://example.com'),INTERNET_DEFAULT_HTTP_PORT,nil,nil,INTERNET_SERVICE_HTTP,0,DWORD(0));
if(hURL<>nil) then
hRequest := HttpOpenRequest(hURL, 'POST', PChar('param=value'),'HTTP/1.0',PChar(''), nil, INTERNET_FLAG_RELOAD or INTERNET_FLAG_PRAGMA_NOCACHE,0);
if(hRequest<>nil) then
HttpSendRequest(hRequest, nil, 0, nil, 0);
InternetCloseHandle(hNet);
except
on E : Exception do
ShowMessage(E.ClassName+' error raised, with message : '+E.Message);
end;
end
end;
但这没有任何作用(我正在嗅探网络 http 流量以查看它是否有效).我已成功使用 InternetOpenURL,但我还需要发送 POST 请求,而该功能没有这样做.
But this doesn't do anything (I am sniffing network http traffic to see if it works). I have successfully used InternetOpenURL but I also need to send POST request and that function doesn't do that.
谁能给我举个简单的例子?我想要的结果是在 var 中以字符串形式获取 http 响应页面.
Could someone show me a simple example? The result I want is to get the http response page in a var as string.
推荐答案
我把所有的 url/filename 部分都和之前的代码搞混了.我现在正在使用这个 来自 Jeff DeVore 并且工作正常:
I got all the url/filename part messed up with the previous code. I'm using this from Jeff DeVore now and it's working fine:
function request(const AUrl, AData: AnsiString; blnSSL: Boolean = True): AnsiString;
var
aBuffer : Array[0..4096] of Char;
Header : TStringStream;
BufStream : TMemoryStream;
sMethod : AnsiString;
BytesRead : Cardinal;
pSession : HINTERNET;
pConnection : HINTERNET;
pRequest : HINTERNET;
parsedURL : TStringArray;
port : Integer;
flags : DWord;
begin
ParsedUrl := ParseUrl(AUrl);
Result := '';
pSession := InternetOpen(nil, INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
if Assigned(pSession) then
try
if blnSSL then
Port := INTERNET_DEFAULT_HTTPS_PORT
else
Port := INTERNET_DEFAULT_HTTP_PORT;
pConnection := InternetConnect(pSession, PChar(ParsedUrl[0]), port, nil, nil, INTERNET_SERVICE_HTTP, 0, 0);
if Assigned(pConnection) then
try
if (AData = '') then
sMethod := 'GET'
else
sMethod := 'POST';
if blnSSL then
flags := INTERNET_FLAG_SECURE or INTERNET_FLAG_KEEP_CONNECTION
else
flags := INTERNET_SERVICE_HTTP;
pRequest := HTTPOpenRequest(pConnection, PChar(sMethod), PChar(ParsedUrl[1]), nil, nil, nil, flags, 0);
if Assigned(pRequest) then
try
Header := TStringStream.Create('');
try
with Header do
begin
WriteString('Host: ' + ParsedUrl[0] + sLineBreak);
WriteString('User-Agent: Custom program 1.0'+SLineBreak);
WriteString('Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'+SLineBreak);
WriteString('Accept-Language: en-us,en;q=0.5' + SLineBreak);
WriteString('Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7'+SLineBreak);
WriteString('Keep-Alive: 300'+ SLineBreak);
WriteString('Connection: keep-alive'+ SlineBreak+SLineBreak);
end;
HttpAddRequestHeaders(pRequest, PChar(Header.DataString), Length(Header.DataString), HTTP_ADDREQ_FLAG_ADD);
if HTTPSendRequest(pRequest, nil, 0, Pointer(AData), Length(AData)) then
begin
BufStream := TMemoryStream.Create;
try
while InternetReadFile(pRequest, @aBuffer, SizeOf(aBuffer), BytesRead) do
begin
if (BytesRead = 0) then Break;
BufStream.Write(aBuffer, BytesRead);
end;
aBuffer[0] := #0;
BufStream.Write(aBuffer, 1);
Result := PChar(BufStream.Memory);
finally
BufStream.Free;
end;
end;
finally
Header.Free;
end;
finally
InternetCloseHandle(pRequest);
end;
finally
InternetCloseHandle(pConnection);
end;
finally
InternetCloseHandle(pSession);
end;
end;
ParseUrl 是一个在主机名/文件名"中拆分 URL 的函数,TStringArray 是一个字符串数组.我明天仍然需要检查代码,但它看起来不错,在我的嗅探器中我看到了正在发送的帖子数据和标题.
ParseUrl is a function that splits a URL in "hostname / filename" and TStringArray is an array of strings. I still have to review the code tomorrow but it looks fine and in my sniffer I saw the post data and headers being sent.
这篇关于如何使用 WinInet api 在 Delphi 中发送 HTTP POST 请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!