2010-06-04 66 views
4

德尔福2010年发送一个HTTP POST请求我想用WinInet的发送德尔福2010年一个HTTP POST请求,但我的脚本不工作;/如何使用WinInet

这是我的德尔福脚本:

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脚本:

$data = $_POST['test']; 
$file = "test.txt"; 
$fp = fopen($file, "a"); 
flock($fp, 2); 
fwrite($fp, $data); 
flock($fp, 3); 
fclose($fp); 
+0

请使用4个空格缩进所有行来格式化您的代码。然后将应用语法高亮显示。 – 2010-06-04 20:54:07

+1

有时自己做起来更容易。您也可以编辑该问题。 – 2010-06-04 21:05:04

+1

哦,我的错误,但没有这个,它仍然不起作用 – noxwow 2010-06-04 21:06:56

回答

16

存在的主要问题:

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

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

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

小问题

  • INTERNET_OPEN_TYPE_PRECONFIG or INTERNET_OPEN_TYPE_PRECONFIG:它是足够用INTERNET_OPEN_TYPE_PRECONFIG

  • DWORD(0)是矫枉过正。 0就足够了。

示例代码

我用下面的代码来发布数据:

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函数。我用下面的代码从网上看了小(单行)文本文件:

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

+1

谢谢,我已经合并这些脚本和脚本现在看起来像这样: http://paste.org/pastebin/view/19370 按预期工作。再次感谢。 – noxwow 2010-06-05 10:20:57

+0

@noxwow“检查”似乎不是一种方法的伟大名称。 – 2010-11-04 00:06:21

+0

即时通讯使用turbo德尔福,它说:[Pascal Fehler] uHTTP.pas(22):E2010不兼容的类型:'字符'和'WideChar'..如何fixx? – Hidden 2013-06-21 07:58:17

2
var 
    BufferIn : INTERNET_BUFFERS; 
    Buffer: array[0..1024] of Byte; 
    FTmp: TSomeStream: 
    FURL: string; 
    ... 
begin 
... // Create FTmp, set FUrl, ... 

    NetHandle := InternetOpen('Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3', 
          INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0); 

    UrlHandle := HttpOpenRequest(NetHandle, 'POST', PChar(FURL), nil, nil, nil, INTERNET_FLAG_NO_CACHE_WRITE, 0); 

    ... // Check handles, etc 
    try 
    BufferIn.dwBufferTotal := FTmp.Size; 

    if not HttpSendRequestEx(UrlHandle, @BufferIn, nil, 0, 0) then 
     raise Exception.CreateFmt('Error on HttpSendRequestEx %d\n', [GetLastError()]); 

    size := FTmp.Read(Buffer, 1024); 
    InternetWriteFile(UrlHandle, @Buffer, size, BytesWritten); 

    while (BytesWritten = size) and (BytesWritten > 0) do 
    begin 
     size := FTmp.Read(Buffer, 1024); 
     InternetWriteFile(UrlHandle, @Buffer, size, BytesWritten); 
    end; 
    finally 
    FTmp.Free; 

    InternetCloseHandle(UrlHandle); 
    InternetCloseHandle(NetHandle); 
    end; 
+0

是否有使用Firefox UserAgent的理由? – 2010-11-04 00:07:31

+1

编号只是一个问题的遗留问题我曾经尝试下载html页面,在那里我得到的信息是“使用真正的浏览器”,而不是我想要的html。 – dmajkic 2010-11-05 08:21:39

1

http://www.utilmind.com上有一个库(称为“用于Delphi 32的HTTPGet组件”)。它将可视化控件安装到组件面板中。 它正是你想要的,所以你可能想看看。