FAQ DelphiConsultez toutes les FAQ

Nombre d'auteurs : 121, nombre de questions : 910, dernière mise à jour : 13 janvier 2018  Ajouter une question

 

Cette FAQ a été réalisée à partir des questions fréquemment posées sur les forums Delphi et Delphi et bases de données de www.developpez.com et de l'expérience personnelle des auteurs.

Nous tenons à souligner que cette FAQ ne garantit en aucun cas que les informations qu'elle propose soient correctes. Les auteurs font le maximum, mais l'erreur est humaine. Cette FAQ ne prétend pas non plus être complète. Si vous souhaitez y apporter des corrections ou la compléter, contactez un responsable (lien au bas de cette page).

Nous espérons que cette FAQ saura répondre à vos attentes. Nous vous en souhaitons une bonne lecture.

L'équipe Delphi de Developpez.com.

Commentez


SommaireComposants IndyIdHTTP (9)
précédent sommaire suivant
 

C'est très simple : il suffit d'utiliser la méthode Get du TIdHTTP et de lui transmettre l'URL du document à rapatrier ainsi que le flux dans lequel le stocker.

Voici un exemple d'une fonction créant dynamiquement le composant pour récupérer la page dans un TStream :

Code Delphi : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
  
procedure DownloadHTTP(const AUrl : string; out DestStream: TStream); 
begin 
  with TIdHTTP.Create(Application) do 
  try 
    try 
      Get(AUrl, DestStream); 
    except 
      on e: Exception do 
        MessageDlg(Format('Erreur : %s',[e.Message]), mtInformation, [mbOK], 0); 
    end; 
  finally 
    Free; 
  end; 
end;

Ainsi, le code suivant rapatrie la page d'accueil du site Developpez.com dans un fichier "c:\test.txt" :

Code Delphi : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
procedure TForm1.Button1Click(Sender: TObject); 
var 
  Fs : TFileStream; 
begin 
  Fs := TFileStream.Create('c:\test.txt', fmCreate); 
  try 
    DownloadHTTP('http://www.developpez.com', TStream(fs)); 
  finally 
    Fs.Free; 
  end; 
end;

Mis à jour le 25 janvier 2014 Reisubar


Par défaut, Indy ne gère pas les redirections : si un code d'erreur entre 300 et 307 du genre "Found" ou "Moved Permanently" est reçu, il lève une exception, et ne rapatrie rien.

Pour que les redirections soient gérées, il faut :

  • Mettre HandleRedirect à True;
  • Renseigner un nombre de redirections maximum (pour éviter une boucle infinie) dans RedirectMaximum. Par défaut, il est à 15, mais peut être modifié.

Mis à jour le 26 janvier 2014 Reisubar

Par défaut, lorsque des pages sont protégées par une méthode d'authentification de type Basic (la fameuse boîte de dialogue de demande de nom d'utilisateur / mot de passe), Indy renvoie une exception EIdHTTPProtocolException : "HTTP/1.1 401 Unauthorized".

Pour valider cette authentification, vous devez encoder directement dans la requête le nom d'utilisateur et le mot de passe dans les propriétés UserName et Password de la propriété Request du TidHTTP. De plus, BasicAuthentication doit être mis à "true".

Code Delphi : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
procedure TForm1.Button1Click(Sender: TObject); 
var 
  Fs : TFileStream; 
begin 
  Fs := TFileStream.Create(IncludeTrailingBackslash( 
    ExtractFilePath(Application.ExeName))+'document.txt', fmCreate); 
  try 
    with IdHTTP do 
    begin 
      Host := '192.168.0.3'; // Hôte 
      Request.Username := 'abc'; // Utilisateur 
      Request.Password := 'abc'; // Mot de passe 
      Request.BasicAuthentication := True; // Auth. BASIC 
      Get('192.168.0.3/', Fs); // Demande le fichier 
    end; 
  finally 
    Fs.Free; 
  end; 
end;


Mis à jour le 26 janvier 2014 Reisubar


Avec un TIdHTTP, il est très facile d'afficher dans une ProgressBar (ou tout autre composant) la progression du téléchargement d'un fichier.

Gérer le début du transfert

L'événement OnWorkBegin est déclenché lorsque une opération de transfert commence. On récupère dans cet événement la taille totale de l'élément à télécharger dans AWorkCountMax et le type d'opération (lecture ou écriture de données) dans AWorkMode.
On a donc à contrôler que c'est bien un événement de lecture de données et à assigner à la ProgressBar (ou autre composant de visualisation) comme maximum la taille reçue :

Code Delphi : Sélectionner tout
1
2
3
4
5
6
7
8
9
procedure TForm1.IdHTTPWorkBegin(Sender: TObject; AWorkMode: TWorkMode; 
  const AWorkCountMax: Integer); 
begin 
  if AWorkMode = wmRead then // Uniquement quand le composant reçoit des données 
  begin 
    ProgressBar.Max := AWorkCountMax; // Maximum = taille de l'élément 
    ProgressBar.Position := 0; // Position à zéro 
  end; 
end;

On initialise également à zéro la position de la ProgressBar pour montrer que le téléchargement commence.

Gérer le transfert

Pendant le transfert, Indy appelle régulièrement l'événement OnWork pour notifier que des nouvelles données arrivent ou sont envoyées. C'est cette procédure qu'on utilise pour incrémenter la position de la ProgressBar :

Code Delphi : Sélectionner tout
1
2
3
4
5
6
procedure TForm1.IdHTTPWork(Sender: TObject; AWorkMode: TWorkMode; 
  const AWorkCount: Integer); 
begin 
  if AWorkMode=wmRead then // Uniquement quand le composant reçoit des données 
    ProgressBar.Position := AWorkCount; 
end;

Gérer la fin du transfert

Il n'y a rien de particulier à faire lorsque le transfert est terminé. Si vous voulez effectuer des opérations à ce stade, implémentez vos fonctions dans l'événement OnWorkEnd. Le code ci-dessus remet par exemple la position de la barre de progression à zéro :

Code Delphi : Sélectionner tout
1
2
3
4
procedure TForm1.IdHTTPWorkEnd(Sender: TObject; AWorkMode: TWorkMode); 
begin 
  ProgressBar.Position := 0; 
end;

A titre d'exemple, voilà une procédure qui déclenche le téléchargement d'un fichier et que vous pouvez utiliser pour vérifier si votre code est bon :

Code Delphi : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
procedure TForm1.btnDownloadClick(Sender: TObject); 
var 
  Fs : TFileStream; 
begin 
  Fs := TFileStream.Create(ExtractFilePath(Application.ExeName) 
    +'demo.exe', fmCreate); // Nom du fichier local 
  with IdHTTP do 
  try 
    try 
      // URL du fichier à télécharger 
      Get('http://rabusier.free.fr/mirrors/astase/ultrabackup_setup.exe', Fs);  
    except 
      On E : EIdException do 
        ShowMessage(Format('Erreur durant le téléchargement : %s',[E.Message])); 
      On E : Exception do 
        ShowMessage(Format('Erreur inconnue : %s',[E.Message])); 
    end; 
  finally 
    Fs.Free; //Liberer le flux 
  end; 
end;


Mis à jour le 26 janvier 2014 Reisubar

Il faut utiliser les mêmes événements que ceux utilisés pour notifier la progression du téléchargement, à savoir OnWorkBegin (lorsque le téléchargement commence), OnWork (pendant le téléchargement) et OnWorkEnd (lorsque le téléchargement est terminé).

On procède ainsi : on stocke la date du début de téléchargement dans un variable TDateTime (celle-ci peut être mise dans la partie "variables privées" du TForm ou TThread parent). Pendant le téléchargement, on divise les octets transférés (accessibles via AWorkCount) par le nombre de secondes passées depuis le téléchargement, calculé avec GetSecondBetween. Pensez à ajouter DateUtils à votre clause uses !

Dans l'exemple ci-dessous, c'est un label qui doit être mis à jour. Cette technique peut bien sûr être appliquée à tout contrôle de la VCL.

Au début du téléchargement

On stocke donc la date courante, et on initialise le texte du label. J'ai supposé que la mise à jour n'était pas fait depuis un thread : l'appel à ProcessMessages() est donc nécessaire pour traiter les messages de rafraîchissement, et voir le label changer de valeur :

Code Delphi : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
procedure TForm1.IdHTTPWorkBegin(Sender: TObject; AWorkMode: TWorkMode; 
  const AWorkCountMax: Integer); 
begin 
  if AWorkMode = wmRead then // Uniquement quand le composant reçoit des données 
  begin 
    Label1.Caption := 'Vous téléchargez à 0 Ko/s '; // Init. label 
    FStartDate := Now; // Stocker la date 
    Application.ProcessMessages; // Demander la MAJ. 
  end; 
end;

Pendant le téléchargement

On divise le nombre d'octets transférés par 1024 pour avoir une taille en kilo-octets, puis par le nombre de secondes de téléchargement calculé en début de fonction.

Code Delphi : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
procedure TForm1.IdHTTPWork(Sender: TObject; AWorkMode: TWorkMode; 
  const AWorkCount: Integer); 
var ElapsedTime : Cardinal; 
begin 
  if AWorkMode = wmRead then // Uniquement pendant la réception de données 
  begin 
    ElapsedTime := SecondsBetween(Now, FStartDate); // Calculer le temps de téléchargement 
    if ElapsedTime > 0 then 
    begin 
      Label1.Caption := Format('Vous téléchargez à %s Ko/s', 
        [FormatFloat('0.00', (AWorkCount/1024)/ElapsedTime)]); // MAJ Label. 
      Application.ProcessMessages; 
    end; 
  end; 
end;

Mis à jour le 26 janvier 2014 Reisubar

Une manière est d'appeller la méthode Get du TidHTTP pour charger une page en lui transmettant les paramètres encodés dans l'URL.

Rappel : La partie contenant les informations à soumettre est séparée de l'adresse du script par un "?", et les paires noms/valeurs sont séparées par le caractère "&".

Code Delphi : Sélectionner tout
IdHttp1.Get('http://localhost/myscript.php?param1=valeur1¶m2=valeur2');

Lorsque les données contiennent des caractères spéciaux ou que les valeurs soumises sont entrées par l'utilisateur, il est plus prudent de les encoder en utilisant la méthode PathEncode de la propriété URL du TidHTTP :

Code Delphi : Sélectionner tout
1
2
3
IdHttp1.Get(Format('http://www.mysite.com/cgi-bin/submit.cgi?nom=%s&prenom=%s', 
  [IdHTTP1.URL.PathEncode(EditNom.Text), 
  IdHTTP1.URL.PathEncode(EditPrenom.Text)]));

Mis à jour le 26 janvier 2014 Reisubar


Il faut utiliser la méthode Post() du TIdHTTP. Celle-ci attend une TStringList contenant une liste de paramètres sous la forme paramètre=valeur. Vous devez donc avant instancier une StringList, la remplir avec les paires nom/valeur représentant les données à soumettre, puis enfin appeler Post() :

Code Delphi : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
procedure TForm1.Button1Click(Sender: TObject); 
var 
  Ts : TStringList; 
begin 
  Ts := TStringList.Create; 
  try 
    Ts.Add('Param1=Valeur1');  
    Ts.Add('Param2=Valeur2'); 
    IdHTTP1.Request.ContentType := 'application/x-www-form-urlencoded';        
    IdHTTP1.Post('http://localhost/myscript.php', Ts); 
  finally 
    Ts.free; 
  end; 
end;


Mis à jour le 26 janvier 2014 Reisubar

Pour récupérer des liens sur une page HTML, on peut se servir du composant TIdHTTP comme cela est montré dans l'exemple ci-dessous :

Code Delphi : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
  
procedure GetLinksInHTMLDoc(URL : string; Links : TStrings);  
var HTTP : TIdHTTP;  
    Content, Link : string;  
    Position : integer;  
    BeginPos : Integer; 
begin  
  HTTP := TIdHTTP.Create(nil);  
  try  
    Links.Clear;  
    Content := HTTP.Get(URL);  
  
    Position := 0;  
    while True do  
    begin  
      Position := PosEx('href', Content, Position+1);  
      if Position = 0 then Break;  
      inc(Position, 4);  
      while (Position < Length(Content)) and (Content[Position] in [#0, #10, #13, ' ']) do inc(Position);  
      if Content[Position] <> '=' then Continue;  
      inc(Position);  
      while (Position < Length(Content)) and (Content[Position] in [#0, #10, #13, ' ']) do inc(Position);  
      if Content[Position] <> '"' then Continue;  
      inc(Position);  
      BeginPos := Position;  
      while (Position <= Length(Content)) and (Content[Position] <> '"') do inc(Position);  
  
      Link := Copy(Content, BeginPos, Position-BeginPos);  
      if (Link <> '') and (Links.IndexOf(Link) = -1) then Links.Add(Link);  
    end;  
  finally  
    HTTP.Free;  
  end;  
end;

Remarque : il faut ajouter l'unité StrUtils dans la clause uses.

Mis à jour le 26 janvier 2014 adaneels sjrd Zaki_SDwin


Le composant TIdHTTP ne possède pas d'équivalent à la méthode Abort comme le composant TIdFTP pour stopper une opération avec le serveur. La solution que je vous propose consiste à interrompre le transfert en provoquant l'appel de EndWork via l'objet IOHandler du TIdHTTP.

Dans notre fiche, nous déclarons un champ privé booléen :

Code Delphi : Sélectionner tout
1
2
3
4
5
6
7
8
  
  TTestForm = class(TForm) 
  private 
    ... 
    FRunning : Boolean; 
  public 
    { Public declarations } 
  end;

Au début du transfert, c'est-à-dire dans l'événement OnWorkBegin de notre TIdHTTP, nous aurons :

Code Delphi : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
  
procedure TTestForm.IdHTTPWorkBegin(ASender: TObject; AWorkMode: TWorkMode; 
  AWorkCountMax: Integer); 
begin 
  if AWorkMode = wmRead then 
  begin 
    FRunning := True; 
    ... 
  end; 
end;

Ensuite, nous déposons un bouton qui nous servira à stopper le téléchargement. Son code sera :

Code Delphi : Sélectionner tout
1
2
3
4
5
  
procedure TTestForm.btnStopClick(Sender: TObject); 
begin 
  FRunning := not FRunning; 
end;

Dans l'événement OnWork, il nous suffira alors d'écrire :

Code Delphi : Sélectionner tout
1
2
3
4
5
6
7
8
  
procedure TTestForm.IdHTTPWork(ASender: TObject; AWorkMode: TWorkMode; AWorkCount: Integer); 
begin 
  ... 
  Application.ProcessMessages; 
  if not Frunning then 
    IdHTTP.IOHandler.CloseGracefully; 
end;

Mis à jour le 26 janvier 2014 Giovanny Temgoua

Proposer une nouvelle réponse sur la FAQ

Ce n'est pas l'endroit pour poser des questions, allez plutôt sur le forum de la rubrique pour ça


Réponse à la question

Liens sous la question
précédent sommaire suivant
 

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2018 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

 
Responsables bénévoles de la rubrique Delphi : Gilles Vasseur - Alcatîz -