FAQ DelphiConsultez toutes les FAQ
Nombre d'auteurs : 124, nombre de questions : 934, dernière mise à jour : 23 octobre 2024 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.
- Comment télécharger un fichier avec un IdHTTP ?
- Comment gérer les redirections ?
- Comment gérer les authentifications de type HTACCESS avec le TIdHTTP ?
- Comment afficher la progression durant un téléchargement ?
- Comment puis-je connaître la vitesse de téléchargement avec un TidHTTP ?
- Comment soumettre des informations à un script par la méthode GET ?
- Comment valider un formulaire ne contenant que des données textuelles avec la méthode POST ?
- Comment récuperer les liens dans une page HTML ?
- Comment stopper un téléchargement par un TIdHTTP ?
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; |
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é.
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; |
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; |
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; |
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)])); |
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; |
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.
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; |
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 çaLes 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 © 2024 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.