Question

Sur un site Web basé sur PHP, je souhaite envoyer aux utilisateurs un package de téléchargement après avoir rempli un court formulaire.Le téléchargement lancé par le site doit être similaire à des sites comme download.com, qui indiquent « votre téléchargement va commencer dans un instant ».

Quelques approches possibles Je connais et la compatibilité du navigateur (basée sur un test rapide) :

1) Faites un window.open pointant vers le nouveau fichier.

- FireFox 3 blocks this.  
 - IE6 blocks this.  
 - IE7 blocks this.

2) Créez une iframe pointant vers le nouveau fichier.

- FireFox 3 seems to think this is OK. (Maybe it's because I already accepted it once?)  
 - IE6 blocks this.  
 - IE7 blocks this.

How can I do this so that at least these three browsers will not object? 

Prime:existe-t-il une méthode qui ne nécessite pas d'instructions conditionnelles du navigateur ?

(Je crois que download.com utilise les deux méthodes de manière conditionnelle, mais je n'arrive pas à faire fonctionner l'une ou l'autre.)

Réponses et précisions :

Q: "Why not point the current window to the file?"  
A: That might work, but in this particular case, I want to show them some other content while their download starts - for example, "would you like to donate to this project?"

MISE À JOUR:J'ai abandonné cette approche.Voir ma réponse ci-dessous pour les raisons.

Était-ce utile?

La solution

Vous pouvez également effectuer une méta-actualisation, prise en charge par la plupart des navigateurs.Download.com en place un dans une balise noscript.

<meta http-equiv="refresh" content="5;url=/download.php?doc=123.zip"/>

Autres conseils

Mise à jour:J'ai décidé d'abandonner cette approche et de simplement présenter à l'utilisateur un lien vers le fichier réel.Mon raisonnement est le suivant :

Mes premières tentatives de téléchargement lancé par le serveur ont été bloquées par le navigateur.Cela m'a fait réfléchir :"le navigateur a raison.Comment il savez-vous qu'il s'agit d'un téléchargement légitime ?Il devrait bloquer un téléchargement qui n'est pas visiblement lancé par l'utilisateur.

Toute méthode que je peux utiliser pour un téléchargement lancé par le serveur pourrait aussi être utilisé par quelqu'un qui souhaite envoyer des logiciels malveillants.Par conséquent, les téléchargements ne doivent avoir lieu que lorsque l'utilisateur demande spécifiquement le fichier en cliquant sur un lien correspondant.

Vous êtes libre d'être en désaccord, et si vous souhaitez quand même lancer un téléchargement, j'espère que ce fil de discussion vous aidera à le faire.

J'ai généralement juste un script PHP qui affiche le fichier directement dans le navigateur avec le type de contenu approprié.

if(file_exists($filename)) {
    header("Pragma:  public");
    header("Expires:  0");
    header("Cache-Control:  must-revalidate, pre-check=0");
    header("Cache-Control:  private", false);
    header("Content-Type:  " . $content-type);
    header("Content-Disposition:  attachment; filename=\"" . basename($filename) . "\";" );
    header("Content-Transfer-Encoding:  binary");
    header("Content-Length:  " . filesize($filename));

    readfile("$filename");
}else{
    print "ERROR:  the file " . basename($filename) . " could not be downloaded because it did not exist.";
}

Le seul inconvénient est que, puisque cela définit l'en-tête HTTP, il doit être appelé avant toute autre sortie.

Mais vous pouvez avoir un lien vers la page de téléchargement PHP et le navigateur affichera une boîte de téléchargement sans gâcher le contenu de la page actuelle.

Un problème est que vous pouvez rencontrer des problèmes avec IE (version 6 en particulier) si les en-têtes ne sont pas configurés « correctement ».

Assurez-vous de définir le bon type de contenu, mais envisagez également de définir les options de cache pour IE (au moins) sur permettre mise en cache.S'il s'agit d'un fichier, l'utilisateur peut l'ouvrir plutôt que de l'enregistrer (par ex.un document MS Word), les premières versions d'IE doivent mettre le fichier en cache, car elles transmettent la demande « d'ouverture » à l'application applicable, pointant vers le fichier qui a été téléchargé dans le cache.

Il existe également un problème connexe : si le cache de l'utilisateur IE6 est plein, il ne sauvegardera pas correctement le fichier (ainsi, lorsque l'application applicable prend la main pour l'ouvrir, elle se plaindra que le fichier est corrompu.

Vous pouvez également désactiver toutes les actions gzip sur les téléchargements (pour IE)

IE6/IE7 ont tous deux des problèmes avec les téléchargements volumineux (par ex.4.x Gigs...) ce n'est pas un scénario probable puisque IE n'a même pas de gestionnaire de téléchargement, mais quelque chose dont il faut être conscient.

Enfin, IE6 ne gère parfois pas correctement un téléchargement "push" s'il a été lancé à partir d'une iframe imbriquée.Je ne sais pas exactement ce qui déclenche le problème, mais je trouve qu'il est plus facile avec IE6 d'éviter ce scénario.

Salut !

@Nathan :J'ai décidé de faire exactement ça :Demandez à mon "getfile.php" de charger tous les éléments nécessaires, puis effectuez un

header("Location: ./$path/$filename");

pour laisser le navigateur lui-même et faire directement ce qu'il pense être correct avec le fichier.Cela fonctionne même bien dans Opera avec moi.

Mais cela posera un problème dans les environnements où aucun accès direct aux fichiers n'est autorisé, dans ce cas vous devrez trouver un autre moyen !(Merci Discordia, mes fichiers sont des PDF publics !)

Cordialement, Basty

Que diriez-vous de changer l’emplacement pour pointer vers le nouveau fichier ?(par exemple.en changeant window.location)

J'ai toujours juste créé une iframe qui pointe vers le fichier.

<iframe src="/download.exe" frameborder="0" height="0" width="0"><a href="/download.exe">Click here to download.</a></iframe>

Concernant le fait de ne pas pointer la fenêtre actuelle vers le téléchargement.D'après mon expérience, vous pouvez toujours afficher votre page « Veuillez faire un don », car les téléchargements (tant qu'ils envoient les en-têtes corrects) ne mettent pas réellement à jour la fenêtre du navigateur.Je fais cela pour les exportations CSV sur l'un de mes sites, et en ce qui concerne l'utilisateur, une fenêtre de fichier sécurisé apparaît simplement.Je recommanderais donc une simple méta-redirection comme l'a montré Soldarnal.

Pour résumer, vous avez 2 objectifs :

  1. démarrer le processus de téléchargement
  2. montrer à l'utilisateur une page avec des options de don

Pour y parvenir, je ferais ce qui suit :

Lorsque votre utilisateur soumet le formulaire, il obtient la page résultante avec des options de don et un texte indiquant que son téléchargement commencera dans 5 secondes.Et dans la section d'en-tête de cette page, vous mettez le code META comme Soldarnal l'a dit :<méta http-equiv="refresh" content="5;url=/download.php?doc=123.zip>

Et c'est tout.

<a href="normaldownload.zip" onclick="use_dhtml_or_ajax_to_display_page()">

La page actuelle n'est pas affectée si le téléchargement est enregistré.Assurez-vous simplement que le téléchargement ne s'ouvre pas dans la même fenêtre (type MIME approprié ou Content-Disposition) et vous pourrez tout montrer.

Voir la réponse plus complète

Vous pouvez utiliser Javascript/jQuery pour lancer le téléchargement.Voici un exemple : vous pouvez vous débarrasser de la requête Ajax et simplement utiliser le bloc setTimeout().

$("btnDownloadCSV").on('click', function() {
    $.ajax({
        url: "php_backend/get_download_url",
        type: 'post',
        contentType: "application/x-www-form-urlencoded",
        data: {somedata: "somedata"},
        success: function(data) {
            // If iFrame already exists, remove it.
            if($("[id^='iframeTempCSV_"]).length) { 
                $("[id^='iframeTempCSV_"]).remove();
            }
            setTimeout(function() {
                //  If I'm creating an iframe with the same id, it will permit download only the first time.
                // So randHashId appended to ID to trick the browser.
                var randHashId = Math.random().toString(36).substr(2);
                // Create a fresh iFrame for auto-downloading CSV
                $('<iframe id="iframeTempCSV_'+randHashId+'" style="display:none;" src="'+data.filepath+'"></iframe>').appendTo('body');
            }, 1000);
        },
        error: function(xhr, textStatus, errorThrown) {
           console.error("Error downloading...");
       }
    });
});
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top