Delphi 用WinInet 单元实现 POST提交数据


由于贪方便,用idhttp控件实现POST部分。结果发现频繁提交的时候总产生10054 等N多不可控错误。遂想换其它方法。百度找了下。基本都是靠webbrowser 、idhttp等控件提交的。于是,摸索着用 wininet.dll的api自己实现了一个webpost。效果不错。特地贴上方便自己以后检索。

代码:

function WebPagePost(sURL,sPostData:string):Pointer;stdcall;

const

  RequestMethod = 'POST';

  HTTP_VERSION  = 'HTTP/1.1';  //HTTP版本 我抓包看过 HTTP/1.0 HTTP/1.1。尚未仔细了解其区别。按MSDN来写的。留空默认是1.0

var

  dwSize:DWORD;

  dwFileSize: Int64;

  dwBytesRead,dwReserved:DWORD;

  hInte,hConnection,hRequest:HInternet;

  ContentSize:array[1..1024] of Char;

  HostPort:Integer;

  HostName,FileName,sHeader:String;

  procedure ParseURL(URL: string;var HostName,FileName:string;var HostPort:Integer);

  var

    i,p,k: DWORD;

    function StrToIntDef(const S: string; Default: Integer): Integer;

    var

      E: Integer;

    begin

      Val(S, Result, E);

      if E <> 0 then Result := Default;

    end;

  begin

    if lstrcmpi('http://',PChar(Copy(URL,1,7))) = 0 then System.Delete(URL, 1, 7);

    HostName := URL;

    FileName := '/';

    HostPort := INTERNET_DEFAULT_HTTP_PORT;

    i := Pos('/', URL);

    if i <> 0 then

    begin

      HostName := Copy(URL, 1, i-1);

      FileName := Copy(URL, i, Length(URL) - i + 1);

    end;

    p:=pos(':',HostName);

    if p <> 0 then

    begin

      k:=Length(HostName)-p;

      HostPort:=StrToIntDef(Copy(HostName,p+1,k),INTERNET_DEFAULT_HTTP_PORT);

      Delete(HostName,p,k+1);

    end;

  end;

begin

  Result := Pointer(-1);

  dwFileSize :=0;

  ParseURL(sURL,HostName,FileName,HostPort);

  // 函数原型见 http://technet.microsoft.com/zh-cn/subscriptions/aa385096(v=vs.85).aspx

  hInte := InternetOpen('', //UserAgent

                           INTERNET_OPEN_TYPE_PRECONFIG,nil,nil,0);

  if hInte<>nil then

  begin

    hConnection := InternetConnect(hInte,   // 函数原型见 http://technet.microsoft.com/zh-cn/query/ms909418

                                   PChar(HostName),

                                   HostPort,

                                   nil,

                                   nil,

                                   INTERNET_SERVICE_HTTP,

                                   0,

                                   0);

    if hConnection<>nil then

    begin

      hRequest := HttpOpenRequest(hConnection,  // 函数原型见 http://msdn.microsoft.com/zh-cn/library/aa917871

                                  PChar(RequestMethod),

                                  PChar(FileName),

                                  HTTP_VERSION,

                                  '', //Referrer 来路

                                  nil,//AcceptTypes 接受的文件类型 TEXT/HTML */*

                                  INTERNET_FLAG_NO_CACHE_WRITE or

                                  INTERNET_FLAG_RELOAD,

                                  0);

      if hRequest<>nil then

      begin

        sHeader := 'Content-Type: application/x-www-form-urlencoded' + #13#10;

    //    +'CLIENT-IP: 216.13.23.33'+#13#10

    //    'X-FORWARDED-FOR: 216.13.23.33' + #13#10+; 伪造代理IP

        // 函数原型见 http://msdn.microsoft.com/zh-cn/library/aa384227(v=VS.85)

        HttpAddRequestHeaders(hRequest,PChar(sHeader),

                              Length(sHeader),

                              HTTP_ADDREQ_FLAG_ADD or HTTP_ADDREQ_FLAG_REPLACE);

        // 函数原型见 http://msdn.microsoft.com/zh-cn/library/windows/desktop/aa384247(v=vs.85).aspx

        if HttpSendRequest(hRequest,nil,0,PChar(sPostData),Length(sPostData)) then

        begin

          dwReserved:=0;

          dwSize:=SizeOf(ContentSize);

          // 函数原型 http://msdn.microsoft.com/zh-cn/subscriptions/downloads/aa384238.aspx

          if HttpQueryInfo(hRequest,HTTP_QUERY_CONTENT_LENGTH,@ContentSize,dwSize,dwReserved) then

          begin

            dwFileSize:=StrToInt(StrPas(@ContentSize));

            GetMem(Result, dwFileSize);

            InternetReadFile(hRequest,Result,dwFileSize,dwBytesRead);

          end;

        end;

      end;

      InternetCloseHandle(hRequest);

    end;

    InternetCloseHandle(hConnection);

  end;

  InternetCloseHandle(hInte);

end;

调用方法:

WebPagePost('http://www.xxx.com/register.php','user=xxx;pass=xxx');


联系电话:
020-00000000
联系电话:
020-00000000
联系电话:
020-12345678