如何使用 WinInet 在 Delphi 2010 中发送 HTTP Post 请求
我想使用 WinInet 在 Delphi 2010 中发送 HTTP Post 请求,但我的脚本不起作用;/
I want to send a HTTP Post Request in Delphi 2010 using WinInet, but my script doesn't work ;/
这是我的 Delphi 脚本:
It's my Delphi script:
uses WinInet;
procedure TForm1.Button1Click(Sender: TObject);
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://localhost/delphitest.php'),INTERNET_DEFAULT_HTTP_PORT,nil,nil,INTERNET_SERVICE_HTTP,0,DWORD(0));
if(hURL<>nil) then
hRequest := HttpOpenRequest(hURL, 'POST', PChar('test=test'),'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
ShowMessage('error');
end
end;
end;
和我的 PHP 脚本:
and my PHP script:
$data = $_POST['test'];
$file = "test.txt";
$fp = fopen($file, "a");
flock($fp, 2);
fwrite($fp, $data);
flock($fp, 3);
fclose($fp);
主要问题:
InternetConnect
的第二个参数应该只包含服务器的名称,而不是服务器端脚本的整个 URL.
The second parameter of
InternetConnect
should contain only the name of the server, not the entire URL of the server-side script.
HttpOpenRequest
的第三个参数应该是脚本的文件名(URL),不是POST数据!
The third parameter of HttpOpenRequest
should be the file name (URL) of the script, not the POST data!
实际的POST数据应该是HttpSendRequest
的第四个参数.
The actual POST data should be the forth parameter of HttpSendRequest
.
小问题
INTERNET_OPEN_TYPE_PRECONFIG 或 INTERNET_OPEN_TYPE_PRECONFIG
:INTERNET_OPEN_TYPE_PRECONFIG
就足够了.
DWORD(0)
太过分了.0
就够了.
DWORD(0)
is overkill. 0
is enough.
示例代码
我使用以下代码来发布数据:
I use the following code to POST data:
procedure WebPostData(const UserAgent: string; const Server: string; const Resource: string; const Data: AnsiString); overload;
var
hInet: HINTERNET;
hHTTP: HINTERNET;
hReq: HINTERNET;
const
accept: packed array[0..1] of LPWSTR = (PChar('*/*'), nil);
header: string = 'Content-Type: application/x-www-form-urlencoded';
begin
hInet := InternetOpen(PChar(UserAgent), INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
try
hHTTP := InternetConnect(hInet, PChar(Server), INTERNET_DEFAULT_HTTP_PORT, nil, nil, INTERNET_SERVICE_HTTP, 0, 1);
try
hReq := HttpOpenRequest(hHTTP, PChar('POST'), PChar(Resource), nil, nil, @accept, 0, 1);
try
if not HttpSendRequest(hReq, PChar(header), length(header), PChar(Data), length(Data)) then
raise Exception.Create('HttpOpenRequest failed. ' + SysErrorMessage(GetLastError));
finally
InternetCloseHandle(hReq);
end;
finally
InternetCloseHandle(hHTTP);
end;
finally
InternetCloseHandle(hInet);
end;
end;
例如:
WebPostData('My UserAgent', 'www.rejbrand.se', 'mydir/myscript.asp', 'value=5');
更新以响应 OP 的回答
要从 Internet 读取数据,请使用 InternetReadFile
函数.我使用以下代码从互联网上读取一个小的(一行)文本文件:
To read data from the Internet, use InternetReadFile
function. I use the following code to read a small (one-line) text file from the Internet:
function WebGetData(const UserAgent: string; const Server: string; const Resource: string): string;
var
hInet: HINTERNET;
hURL: HINTERNET;
Buffer: array[0..1023] of AnsiChar;
i, BufferLen: cardinal;
begin
result := '';
hInet := InternetOpen(PChar(UserAgent), INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
try
hURL := InternetOpenUrl(hInet, PChar('http://' + Server + Resource), nil, 0, 0, 0);
try
repeat
InternetReadFile(hURL, @Buffer, SizeOf(Buffer), BufferLen);
if BufferLen = SizeOf(Buffer) then
result := result + AnsiString(Buffer)
else if BufferLen > 0 then
for i := 0 to BufferLen - 1 do
result := result + Buffer[i];
until BufferLen = 0;
finally
InternetCloseHandle(hURL);
end;
finally
InternetCloseHandle(hInet);
end;
end;
示例用法:
WebGetData('My UserAgent', 'www.rejbrand.se', '/MyDir/update/ver.txt')
这个函数因此只读取数据,没有事先的POST.但是,InternetReadFile
函数也可以与 HttpOpenRequest
创建的句柄一起使用,因此它也适用于您的情况.您确实知道 WinInet 参考是 MSDN,对吗?那里详细描述了所有 Windows API 函数,例如 InternetReadFile.
This function thus only reads data, with no prior POST. However, the InternetReadFile
function can also be used with a handle created by HttpOpenRequest
, so it will work in your case also. You do know that the WinInet reference is MSDN, right? All Windows API functions are described in detail there, for instance InternetReadFile.