且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何使用WinInet在Delphi 2010中发送HTTP发布请求

更新时间:2022-10-29 13:22:56

主要问题: / p>


  • InternetConnect 的第二个参数应该只包含服务器的名称而不是服务器端脚本的整个URL。


  • HttpOpenRequest 的第三个参数应为脚本的文件名(URL),而不是POST数据!


  • 实际的POST数据应该是 HttpSendRequest的第四个参数




次要问题




  • INTERNET_OPEN_TYPE_PRECONFIG或INTERNET_OPEN_TYPE_PRECONFIG :只需 INTERNET_OPEN_TYPE_PRECONFIG


  • DWORD(0)




示例代码



我使用以下代码来POST数据:

  procedure WebPostData(const UserAgent:string; const Server:string; const Resource:string; const Data:AnsiString);超载; 
var
hInet:HINTERNET;
hHTTP:HINTERNET;
hReq:HINTERNET;
const
接受:LPWSTR =(PChar('* / *'),nil)的包数组[0..1];
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);
尝试
如果不是HttpSendRequest(hReq,PChar(header),length(header),PChar(Data),length(Data))然后
raise Exception.Create('HttpOpenRequest failed' + SysErrorMessage(GetLastError));
finally
InternetCloseHandle(hReq);
结束
finally
InternetCloseHandle(hHTTP);
结束
finally
InternetCloseHandle(hInet);
结束
结束

例如:

  WebPostData('My UserAgent','www.rejbrand.se','mydir / myscript.asp','value = 5'); 

响应OP的回答更新



要从Internet读取数据,请使用 InternetReadFile 函数。我使用以下代码从Internet中读取一个小的(单行)文本文件:

  function WebGetData(const UserAgent: string; const Server:string; const Resource:string):string; 
var
hInet:HINTERNET;
hURL:HINTERNET;
缓冲区:AnsiChar的数组[0..1023];
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);
尝试
重复
InternetReadFile(hURL,@Buffer,SizeOf(Buffer),BufferLen);
如果BufferLen = SizeOf(Buffer)然后
result:= result + AnsiString(Buffer)
如果BufferLen> 0 then
for i:= 0 to BufferLen - 1 do
result:= result + Buffer [i];
,直到BufferLen = 0;
finally
InternetCloseHandle(hURL);
结束
finally
InternetCloseHandle(hInet);
结束
结束

样本使用情况:

  WebGetData('My UserAgent','www.rejbrand.se','/MyDir/update/ver.txt')

因此,此函数只读取数据,而不需要先前的POST。但是, InternetReadFile 函数也可以与由 HttpOpenRequest 创建的句柄一起使用,因此它也适用于您的情况。你知道 WinInet引用是MSDN,对吧?所有Windows API功能都将在此详细描述,例如 InternetReadFile


I want to send a HTTP Post Request in Delphi 2010 using WinInet, but my script doesn't work ;/

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;

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

Major problems:

  • The second parameter of InternetConnect should contain only the name of the server, not the entire URL of the server-side script.

  • The third parameter of HttpOpenRequest should be the file name (URL) of the script, not the POST data!

  • The actual POST data should be the forth parameter of HttpSendRequest.

Minor problems

  • INTERNET_OPEN_TYPE_PRECONFIG or INTERNET_OPEN_TYPE_PRECONFIG: It is sufficient with INTERNET_OPEN_TYPE_PRECONFIG.

  • DWORD(0) is overkill. 0 is enough.

Sample Code

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;

For instance:

WebPostData('My UserAgent', 'www.rejbrand.se', 'mydir/myscript.asp', 'value=5');

Update in response to answer by OP

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;

Sample usage:

WebGetData('My UserAgent', 'www.rejbrand.se', '/MyDir/update/ver.txt')

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.