2010-06-04 4 views
4

Je veux envoyer une demande HTTP Post en Delphi 2010 en utilisant WinInet, mais mon script ne fonctionne pas;/Comment envoyer une demande HTTP Post en Delphi 2010 en utilisant WinInet

Il est mon 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(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; 

et mon script PHP:

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

Veuillez formater votre code en indentant toutes les lignes avec 4 espaces. La syntaxe en surbrillance sera ensuite appliquée. –

+1

Parfois, il est plus facile de le faire vous-même. Vous êtes également autorisé à modifier la question. –

+1

oh, mon erreur, mais sans cela, il ne fonctionne toujours pas – noxwow

Répondre

16

problèmes majeurs:

  • Le second paramètre de InternetConnect ne doit contenir que le nom du serveur et non l'URL complète du script côté serveur.

  • Le troisième paramètre de HttpOpenRequest devrait être le nom de fichier (URL) du script, pas les données POST!

  • Les données POST réelles doivent être le quatrième paramètre de HttpSendRequest.

Problèmes mineurs

  • INTERNET_OPEN_TYPE_PRECONFIG or INTERNET_OPEN_TYPE_PRECONFIG: Il suffit de INTERNET_OPEN_TYPE_PRECONFIG.

  • DWORD(0) est surchargé. 0 est suffisant.

Exemple de code

J'utilise le code suivant à données 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; 

Par exemple:

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

mise à jour en réponse à répondre par OP

Pour lire les données à partir d'Internet, utilisez la fonction InternetReadFile. J'utilise le code suivant pour lire un petit (une ligne) fichier texte à partir de l'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; 

Exemple d'utilisation:

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

Cette fonction lit ainsi que des données, sans POST avant. Cependant, la fonction InternetReadFile peut également être utilisée avec une poignée créée par HttpOpenRequest, elle fonctionnera donc aussi dans votre cas. Vous savez que la référence WinInet est MSDN, non? Toutes les fonctions de l'API Windows sont décrites en détail, par exemple InternetReadFile.

+1

Merci, j'ai fusionné ces scripts et le script ressemble maintenant à ceci: http://paste.org/pastebin/view/19370 Fonctionne comme prévu. Merci encore. – noxwow

+0

@noxwow "Check" ne semble pas être un grand nom pour une méthode. –

+0

Im en utilisant turbo delphi et il dit: [Pascal Fehler] uHTTP.pas (22): E2010 types incompatibles: 'Char' et 'WideChar' .. Comment fixerx? – Hidden

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

Y a-t-il une raison pour laquelle vous utilisez Firefox UserAgent? –

+1

Non. Juste un reste de problème que j'avais une fois essayé de télécharger la page html où j'ai reçu un message pour "utiliser un vrai navigateur" au lieu de html je voulais. – dmajkic

1

Il y a une bibliothèque (appelée 'HttpGet composant pour Delphi 32') sur http://www.utilmind.com.Il installe un contrôle visuel dans votre palette de composants. Il fait exactement ce que vous voulez, alors vous pouvez jeter un oeil.

Questions connexes