Come inviare una richiesta HTTP Post in Delphi 2010 utilizzando WinInet

Voglio inviare una richiesta HTTP Post in Delphi 2010 utilizzando WinInet, ma il mio script non funziona; /

È il mio script Delphi:

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(hURLnil) then hRequest := HttpOpenRequest(hURL, 'POST', PChar('test=test'),'HTTP/1.0',PChar(''), nil, INTERNET_FLAG_RELOAD or INTERNET_FLAG_PRAGMA_NOCACHE,0); if(hRequestnil) then HttpSendRequest(hRequest, nil, 0, nil, 0); InternetCloseHandle(hNet); except ShowMessage('error'); end end; end; 

e il mio script PHP:

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

    Problemi principali:

    • Il secondo parametro di InternetConnect dovrebbe contenere solo il nome del server, non l’intero URL dello script sul lato server.

    • Il terzo parametro di HttpOpenRequest dovrebbe essere il nome del file (URL) dello script, non i dati POST!

    • I dati POST effettivi dovrebbero essere il quarto parametro di HttpSendRequest .

    Problemi minori

    • INTERNET_OPEN_TYPE_PRECONFIG or INTERNET_OPEN_TYPE_PRECONFIG : è sufficiente con INTERNET_OPEN_TYPE_PRECONFIG .

    • DWORD(0) è eccessivo. 0 è sufficiente.

    Codice d’esempio

    Io uso il seguente codice per i dati POST:

     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; 

    Per esempio:

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

    Aggiornamento in risposta alla risposta di OP

    Per leggere i dati da Internet, utilizzare InternetReadFile funzione InternetReadFile . Io uso il seguente codice per leggere un piccolo file di testo (su una riga) da 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; 

    Esempio di utilizzo:

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

    Questa funzione pertanto legge solo i dati, senza alcun POST precedente. Tuttavia, la funzione InternetReadFile può anche essere utilizzata con un handle creato da HttpOpenRequest , quindi funzionerà anche nel tuo caso. Sai che il riferimento WinInet è MSDN, giusto? Tutte le funzioni dell’API di Windows sono descritte in dettaglio qui, ad esempio InternetReadFile .

     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; 

    Esiste una libreria (chiamata “componente HTTPGet per Delphi 32”) su http://www.utilmind.com . Installa un controllo visivo nella tavolozza dei componenti. Fa esattamente quello che vuoi, quindi potresti voler dare un’occhiata.